Merge branch 'main' into urdu-lang
128
.github/CODE_OF_CONDUCT.md
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
report@ghost.org.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -7,8 +7,3 @@ Please include a description of your change & check your PR against this list, t
|
|||
- [ ] The build will pass (run `yarn test:all` and `yarn lint`)
|
||||
|
||||
We appreciate your contribution!
|
||||
|
||||
---
|
||||
|
||||
<!-- Leave the line below if you'd like GitHub Copilot to generate a summary from your commit -->
|
||||
copilot:summary
|
||||
|
|
7
.github/labeler.yml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
'affects:i18n':
|
||||
- 'ghost/i18n/**'
|
||||
'affects:admin':
|
||||
- 'ghost/admin/**'
|
||||
- 'apps/admin-x-*/**'
|
||||
'affects:portal':
|
||||
- 'apps/portal/**'
|
40
.github/scripts/dev.js
vendored
|
@ -2,6 +2,7 @@ const path = require('path');
|
|||
const util = require('util');
|
||||
const exec = util.promisify(require('child_process').exec);
|
||||
|
||||
const chalk = require('chalk');
|
||||
const concurrently = require('concurrently');
|
||||
|
||||
// check we're running on Node 18 and above
|
||||
|
@ -44,32 +45,40 @@ const COMMAND_ADMIN = {
|
|||
|
||||
const COMMAND_TYPESCRIPT = {
|
||||
name: 'ts',
|
||||
command: 'nx watch --projects=ghost/collections,ghost/in-memory-repository,ghost/bookshelf-repository,ghost/mail-events,ghost/model-to-domain-event-interceptor,ghost/post-revisions,ghost/nql-filter-expansions,ghost/post-events,ghost/donations,ghost/recommendations -- nx run \\$NX_PROJECT_NAME:build:ts',
|
||||
command: 'nx watch --projects=ghost/collections,ghost/in-memory-repository,ghost/bookshelf-repository,ghost/mail-events,ghost/model-to-domain-event-interceptor,ghost/post-revisions,ghost/nql-filter-expansions,ghost/post-events,ghost/donations,ghost/recommendations,ghost/email-addresses -- nx run \\$NX_PROJECT_NAME:build:ts',
|
||||
cwd: path.resolve(__dirname, '../../'),
|
||||
prefixColor: 'cyan',
|
||||
env: {}
|
||||
};
|
||||
|
||||
const COMMAND_ADMINX = {
|
||||
const adminXApps = '@tryghost/admin-x-demo,@tryghost/admin-x-settings';
|
||||
|
||||
const COMMANDS_ADMINX = [{
|
||||
name: 'adminXDeps',
|
||||
command: 'nx watch --projects=apps/admin-x-design-system,apps/admin-x-framework -- nx run \\$NX_PROJECT_NAME:build --skip-nx-cache',
|
||||
cwd: path.resolve(__dirname, '../..'),
|
||||
prefixColor: '#C35831',
|
||||
env: {}
|
||||
}, {
|
||||
name: 'adminX',
|
||||
command: 'yarn dev',
|
||||
command: `nx run-many --projects=${adminXApps} --targets=build && nx run-many --projects=${adminXApps} --parallel=${adminXApps.length} --targets=dev`,
|
||||
cwd: path.resolve(__dirname, '../../apps/admin-x-settings'),
|
||||
prefixColor: '#C35831',
|
||||
env: {}
|
||||
};
|
||||
}];
|
||||
|
||||
if (DASH_DASH_ARGS.includes('ghost')) {
|
||||
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT];
|
||||
} else if (DASH_DASH_ARGS.includes('admin')) {
|
||||
commands = [COMMAND_ADMIN, COMMAND_ADMINX];
|
||||
commands = [COMMAND_ADMIN, ...COMMANDS_ADMINX];
|
||||
} else {
|
||||
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT, COMMAND_ADMIN, COMMAND_ADMINX];
|
||||
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT, COMMAND_ADMIN, ...COMMANDS_ADMINX];
|
||||
}
|
||||
|
||||
if (DASH_DASH_ARGS.includes('portal') || DASH_DASH_ARGS.includes('all')) {
|
||||
commands.push({
|
||||
name: 'portal',
|
||||
command: 'yarn dev',
|
||||
command: 'nx run @tryghost/portal:dev',
|
||||
cwd: path.resolve(__dirname, '../../apps/portal'),
|
||||
prefixColor: 'magenta',
|
||||
env: {}
|
||||
|
@ -92,7 +101,7 @@ if (DASH_DASH_ARGS.includes('portal') || DASH_DASH_ARGS.includes('all')) {
|
|||
if (DASH_DASH_ARGS.includes('signup') || DASH_DASH_ARGS.includes('all')) {
|
||||
commands.push({
|
||||
name: 'signup-form',
|
||||
command: DASH_DASH_ARGS.includes('signup') ? 'yarn dev' : 'yarn preview',
|
||||
command: DASH_DASH_ARGS.includes('signup') ? 'nx run @tryghost/signup-form:dev' : 'nx run @tryghost/signup-form:preview',
|
||||
cwd: path.resolve(__dirname, '../../apps/signup-form'),
|
||||
prefixColor: 'magenta',
|
||||
env: {}
|
||||
|
@ -103,7 +112,7 @@ if (DASH_DASH_ARGS.includes('signup') || DASH_DASH_ARGS.includes('all')) {
|
|||
if (DASH_DASH_ARGS.includes('announcement-bar') || DASH_DASH_ARGS.includes('announcementBar') || DASH_DASH_ARGS.includes('announcementbar') || DASH_DASH_ARGS.includes('all')) {
|
||||
commands.push({
|
||||
name: 'announcement-bar',
|
||||
command: 'yarn dev',
|
||||
command: 'nx run @tryghost/announcement-bar:dev',
|
||||
cwd: path.resolve(__dirname, '../../apps/announcement-bar'),
|
||||
prefixColor: '#DC9D00',
|
||||
env: {}
|
||||
|
@ -114,7 +123,7 @@ if (DASH_DASH_ARGS.includes('announcement-bar') || DASH_DASH_ARGS.includes('anno
|
|||
if (DASH_DASH_ARGS.includes('search') || DASH_DASH_ARGS.includes('all')) {
|
||||
commands.push({
|
||||
name: 'search',
|
||||
command: 'yarn dev',
|
||||
command: 'nx run @tryghost/sodo-search:dev',
|
||||
cwd: path.resolve(__dirname, '../../apps/sodo-search'),
|
||||
prefixColor: '#23de43',
|
||||
env: {}
|
||||
|
@ -153,7 +162,7 @@ if (DASH_DASH_ARGS.includes('comments') || DASH_DASH_ARGS.includes('all')) {
|
|||
|
||||
commands.push({
|
||||
name: 'comments',
|
||||
command: 'yarn dev',
|
||||
command: 'nx run @tryghost/comments-ui:dev',
|
||||
cwd: path.resolve(__dirname, '../../apps/comments-ui'),
|
||||
prefixColor: '#E55137',
|
||||
env: {}
|
||||
|
@ -165,7 +174,6 @@ async function handleStripe() {
|
|||
if (DASH_DASH_ARGS.includes('offline')) {
|
||||
return;
|
||||
}
|
||||
console.log('Fetching Stripe secret token..');
|
||||
|
||||
let stripeSecret;
|
||||
try {
|
||||
|
@ -198,6 +206,8 @@ async function handleStripe() {
|
|||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log(`Running projects: ${commands.map(c => chalk.green(c.name)).join(', ')}`);
|
||||
|
||||
const {result} = concurrently(commands, {
|
||||
prefix: 'name',
|
||||
killOthers: ['failure', 'success']
|
||||
|
@ -206,6 +216,10 @@ async function handleStripe() {
|
|||
try {
|
||||
await result;
|
||||
} catch (err) {
|
||||
console.error('\nExecuting dev command failed, ensure dependencies are up-to-date by running `yarn fix`\n');
|
||||
console.error();
|
||||
console.error(chalk.red(`Executing dev command failed:`) + `\n`);
|
||||
console.error(chalk.red(`If you've recently done a \`yarn main\`, dependencies might be out of sync. Try running \`${chalk.green('yarn fix')}\` to fix this.`));
|
||||
console.error(chalk.red(`If not, something else went wrong. Please report this to the Ghost team.`));
|
||||
console.error();
|
||||
}
|
||||
})();
|
||||
|
|
113
.github/workflows/browser-tests.yml
vendored
|
@ -1,113 +0,0 @@
|
|||
name: Browser Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
environment:
|
||||
description: 'Environment to run tests against'
|
||||
type: environment
|
||||
required: true
|
||||
site_url:
|
||||
description: 'Site URL (override)'
|
||||
required: false
|
||||
type: string
|
||||
owner_email:
|
||||
description: 'Owner email (override)'
|
||||
required: false
|
||||
type: string
|
||||
owner_password:
|
||||
description: 'Owner password (override)'
|
||||
required: false
|
||||
type: string
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && !startsWith(github.head_ref, 'renovate/'))
|
||||
environment: ${{ github.event.inputs.environment || 'browser-tests-local' }}
|
||||
env:
|
||||
ENVIRONMENT: ${{ github.event.inputs.environment || 'browser-tests-local' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.x'
|
||||
cache: yarn
|
||||
|
||||
- name: Install Stripe-CLI
|
||||
run: |
|
||||
export VERSION=1.13.5
|
||||
wget "https://github.com/stripe/stripe-cli/releases/download/v$VERSION/stripe_${VERSION}_linux_x86_64.tar.gz"
|
||||
tar -zxvf "stripe_${VERSION}_linux_x86_64.tar.gz"
|
||||
mv stripe /usr/local/bin
|
||||
stripe -v
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: Build packages
|
||||
run: yarn nx run-many -t build:ts
|
||||
|
||||
- name: Run migrations
|
||||
working-directory: ghost/core
|
||||
run: yarn knex-migrator init
|
||||
|
||||
- name: Get Playwright version
|
||||
id: playwright-version
|
||||
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v3
|
||||
name: Check if Playwright browser is cached
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-Playwright-${{steps.playwright-version.outputs.version}}
|
||||
- name: Install Playwright browser if not cached
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: npx playwright install --with-deps
|
||||
- name: Install OS dependencies of Playwright if cache hit
|
||||
if: steps.playwright-cache.outputs.cache-hit == 'true'
|
||||
run: npx playwright install-deps
|
||||
|
||||
- name: Build Admin
|
||||
if: env.ENVIRONMENT == 'browser-tests-local'
|
||||
working-directory: ghost/admin
|
||||
run: yarn build:dev
|
||||
|
||||
- name: Run Playwright tests on a remote site
|
||||
if: env.ENVIRONMENT == 'browser-tests-staging'
|
||||
working-directory: ghost/core
|
||||
run: yarn test:browser
|
||||
env:
|
||||
TEST_URL: ${{ github.event.inputs.site_url || secrets.TEST_URL }}
|
||||
TEST_OWNER_EMAIL: ${{ github.event.inputs.owner_email || secrets.TEST_OWNER_EMAIL }}
|
||||
TEST_OWNER_PASSWORD: ${{ github.event.inputs.owner_password || secrets.TEST_OWNER_PASSWORD }}
|
||||
|
||||
- name: Run Playwright tests locally
|
||||
if: env.ENVIRONMENT == 'browser-tests-local'
|
||||
working-directory: ghost/core
|
||||
run: yarn test:browser
|
||||
env:
|
||||
STRIPE_PUBLISHABLE_KEY: ${{ secrets.STRIPE_PUBLISHABLE_KEY }}
|
||||
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
|
||||
STRIPE_ACCOUNT_ID: ${{ secrets.STRIPE_ACCOUNT_ID }}
|
||||
|
||||
- uses: tryghost/actions/actions/slack-build@main
|
||||
if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
with:
|
||||
status: ${{ job.status }}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: browser-tests-playwright-report
|
||||
path: ghost/core/playwright-report
|
||||
retention-days: 30
|
202
.github/workflows/ci.yml
vendored
|
@ -12,7 +12,6 @@ on:
|
|||
env:
|
||||
FORCE_COLOR: 1
|
||||
HEAD_COMMIT: ${{ github.sha }}
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
CACHED_DEPENDENCY_PATHS: |
|
||||
${{ github.workspace }}/node_modules
|
||||
${{ github.workspace }}/apps/*/node_modules
|
||||
|
@ -43,6 +42,11 @@ jobs:
|
|||
ref: ${{ env.HEAD_COMMIT }}
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Output GitHub context
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
|
||||
- name: Get metadata (push)
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
|
@ -115,6 +119,7 @@ jobs:
|
|||
base_commit: ${{ env.BASE_COMMIT }}
|
||||
is_canary_branch: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/arch') }}
|
||||
is_main: ${{ github.ref == 'refs/heads/main' }}
|
||||
has_browser_tests_label: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'browser-tests') }}
|
||||
|
||||
job_install_deps:
|
||||
name: Install Dependencies
|
||||
|
@ -166,7 +171,7 @@ jobs:
|
|||
key: ${{ env.HEAD_COMMIT }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -191,7 +196,7 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -216,6 +221,29 @@ jobs:
|
|||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
job_i18n:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [job_get_metadata, job_install_deps]
|
||||
name: i18n
|
||||
if: |
|
||||
needs.job_get_metadata.outputs.changed_comments_ui == 'true'
|
||||
|| needs.job_get_metadata.outputs.changed_signup_form == 'true'
|
||||
|| needs.job_get_metadata.outputs.changed_portal == 'true'
|
||||
|| needs.job_get_metadata.outputs.changed_core == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18.12.1"
|
||||
|
||||
- name: Restore caches
|
||||
uses: ./.github/actions/restore-cache
|
||||
env:
|
||||
DEPENDENCY_CACHE_KEY: ${{ needs.job_install_deps.outputs.dependency_cache_key }}
|
||||
|
||||
- name: Run i18n tests
|
||||
run: yarn nx run @tryghost/i18n:test
|
||||
|
||||
job_admin-tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [job_get_metadata, job_install_deps]
|
||||
|
@ -228,7 +256,7 @@ jobs:
|
|||
COVERAGE: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18.12.1"
|
||||
|
||||
|
@ -257,6 +285,132 @@ jobs:
|
|||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
job_browser-tests:
|
||||
name: Browser tests
|
||||
timeout-minutes: 60
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4-cores
|
||||
needs: [job_get_metadata, job_install_deps]
|
||||
if: needs.job_get_metadata.outputs.changed_any_code == 'true' && (needs.job_get_metadata.outputs.is_main == 'true' || needs.job_get_metadata.outputs.has_browser_tests_label == 'true')
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
node-version: '18.x'
|
||||
cache: yarn
|
||||
|
||||
- name: Install Stripe-CLI
|
||||
run: |
|
||||
export VERSION=1.13.5
|
||||
wget "https://github.com/stripe/stripe-cli/releases/download/v$VERSION/stripe_${VERSION}_linux_x86_64.tar.gz"
|
||||
tar -zxvf "stripe_${VERSION}_linux_x86_64.tar.gz"
|
||||
mv stripe /usr/local/bin
|
||||
stripe -v
|
||||
|
||||
- name: Restore caches
|
||||
uses: ./.github/actions/restore-cache
|
||||
env:
|
||||
DEPENDENCY_CACHE_KEY: ${{ needs.job_install_deps.outputs.dependency_cache_key }}
|
||||
|
||||
- name: Run migrations
|
||||
working-directory: ghost/core
|
||||
run: yarn knex-migrator init
|
||||
|
||||
- name: Get Playwright version
|
||||
id: playwright-version
|
||||
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v3
|
||||
name: Check if Playwright browser is cached
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-Playwright-${{steps.playwright-version.outputs.version}}
|
||||
- name: Install Playwright browser if not cached
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: npx playwright install --with-deps
|
||||
- name: Install OS dependencies of Playwright if cache hit
|
||||
if: steps.playwright-cache.outputs.cache-hit == 'true'
|
||||
run: npx playwright install-deps
|
||||
|
||||
- name: Build Admin
|
||||
run: yarn nx run ghost-admin:build:dev
|
||||
|
||||
- name: Run Playwright tests locally
|
||||
working-directory: ghost/core
|
||||
run: yarn test:browser
|
||||
env:
|
||||
CI: true
|
||||
STRIPE_PUBLISHABLE_KEY: ${{ secrets.STRIPE_PUBLISHABLE_KEY }}
|
||||
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
|
||||
|
||||
- uses: tryghost/actions/actions/slack-build@main
|
||||
if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
with:
|
||||
status: ${{ job.status }}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: browser-tests-playwright-report
|
||||
path: ghost/core/playwright-report
|
||||
retention-days: 30
|
||||
|
||||
job_perf-tests:
|
||||
runs-on:
|
||||
labels: ubuntu-latest-4-cores
|
||||
needs: [job_get_metadata, job_install_deps]
|
||||
if: needs.job_get_metadata.outputs.changed_core == 'true' && needs.job_get_metadata.outputs.is_main == 'true'
|
||||
name: Performance tests
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
node-version: '18.12.1'
|
||||
|
||||
- name: Restore caches
|
||||
uses: ./.github/actions/restore-cache
|
||||
env:
|
||||
DEPENDENCY_CACHE_KEY: ${{ needs.job_install_deps.outputs.dependency_cache_key }}
|
||||
|
||||
- name: Install hyperfine
|
||||
run: |
|
||||
export HYPERFINE_VERSION=1.18.0
|
||||
wget https://github.com/sharkdp/hyperfine/releases/download/v$HYPERFINE_VERSION/hyperfine-v$HYPERFINE_VERSION-x86_64-unknown-linux-gnu.tar.gz
|
||||
tar -zxvf hyperfine-v$HYPERFINE_VERSION-x86_64-unknown-linux-gnu.tar.gz
|
||||
mv hyperfine-v$HYPERFINE_VERSION-x86_64-unknown-linux-gnu/hyperfine /usr/local/bin
|
||||
chmod +x /usr/local/bin/hyperfine
|
||||
|
||||
- name: Run hyperfine on boot
|
||||
working-directory: ghost/core
|
||||
run: hyperfine --show-output --warmup 3 'GHOST_CI_SHUTDOWN_AFTER_BOOT=1 node index.js' --export-json boot-perf.json
|
||||
|
||||
- name: Convert data
|
||||
working-directory: ghost/core
|
||||
run: |
|
||||
jq '[{ name: "Boot time", unit: "s", value: .results[0].median, range: ((.results[0].max - .results[0].min) | tostring) }]' < boot-perf.json > boot-perf-formatted.json
|
||||
|
||||
- name: Run analysis
|
||||
uses: benchmark-action/github-action-benchmark@v1.18.0
|
||||
with:
|
||||
tool: 'customSmallerIsBetter'
|
||||
output-file-path: ghost/core/boot-perf-formatted.json
|
||||
benchmark-data-dir-path: ""
|
||||
gh-repository: github.com/TryGhost/Ghost-Benchmarks
|
||||
github-token: ${{ secrets.CANARY_DOCKER_BUILD }}
|
||||
auto-push: true
|
||||
|
||||
job_unit-tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [job_get_metadata, job_install_deps]
|
||||
|
@ -269,7 +423,7 @@ jobs:
|
|||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -316,7 +470,7 @@ jobs:
|
|||
name: Database tests (Node ${{ matrix.node }}, ${{ matrix.env.DB }})
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -437,7 +591,9 @@ jobs:
|
|||
name: Regression tests (Node ${{ matrix.node }}, ${{ matrix.env.DB }})
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -488,7 +644,7 @@ jobs:
|
|||
CI: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -541,7 +697,7 @@ jobs:
|
|||
CI: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -594,7 +750,7 @@ jobs:
|
|||
CI: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -648,7 +804,7 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
|
@ -671,6 +827,22 @@ jobs:
|
|||
- run: mv ghost-*.tgz ghost.tgz
|
||||
working-directory: ghost/core
|
||||
|
||||
- name: Install latest v4
|
||||
run: |
|
||||
DIR=$(mktemp -d)
|
||||
echo "V4_DIR=$DIR" >> $GITHUB_ENV
|
||||
ghost install v4 --local -d $DIR
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
env:
|
||||
FORCE_COLOR: 0
|
||||
with:
|
||||
node-version: '18.12.1'
|
||||
|
||||
- name: Update from v4
|
||||
run: |
|
||||
ghost update -f -d $V4_DIR --archive $(pwd)/ghost/core/ghost.tgz
|
||||
|
||||
- name: Clean Install
|
||||
run: |
|
||||
DIR=$(mktemp -d)
|
||||
|
@ -682,12 +854,6 @@ jobs:
|
|||
ghost install local -d $DIR
|
||||
ghost update -d $DIR --archive $(pwd)/ghost/core/ghost.tgz
|
||||
|
||||
- name: Update from latest v4
|
||||
run: |
|
||||
DIR=$(mktemp -d)
|
||||
ghost install v4 --local -d $DIR
|
||||
ghost update -f -d $DIR --archive $(pwd)/ghost/core/ghost.tgz
|
||||
|
||||
- name: Print debug logs
|
||||
if: failure()
|
||||
run: |
|
||||
|
@ -753,11 +919,13 @@ jobs:
|
|||
job_get_metadata,
|
||||
job_install_deps,
|
||||
job_lint,
|
||||
job_i18n,
|
||||
job_ghost-cli,
|
||||
job_admin-tests,
|
||||
job_unit-tests,
|
||||
job_database-tests,
|
||||
job_regression-tests,
|
||||
job_browser-tests,
|
||||
job_admin_x_settings,
|
||||
job_comments_ui,
|
||||
job_signup_form,
|
||||
|
|
21
.github/workflows/i18n.yml
vendored
|
@ -1,21 +0,0 @@
|
|||
name: i18n check
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
paths:
|
||||
- 'ghost/i18n/locales/**'
|
||||
jobs:
|
||||
create-label:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'TryGhost'
|
||||
name: Add i18n label
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ["i18n"]
|
||||
})
|
11
.github/workflows/labeler.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
name: PR labeler
|
||||
on:
|
||||
- pull_request_target
|
||||
jobs:
|
||||
triage:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
2
.github/workflows/migration-review.yml
vendored
|
@ -21,7 +21,7 @@ jobs:
|
|||
labels: ["migration"]
|
||||
})
|
||||
|
||||
- uses: peter-evans/create-or-update-comment@ddff993e3c91296d410ace8836568b0e4aeada34
|
||||
- uses: peter-evans/create-or-update-comment@ac8e6509d7545ebc2e5e7c35eaa12195c2f77adc
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
Love open source? <a href="https://careers.ghost.org">We're hiring</a> JavaScript engineers to work on Ghost full-time.
|
||||
Love open source? <a href="https://careers.ghost.org/devops-engineer">We're hiring</a> DevOps engineers to work on Ghost full-time.
|
||||
</p>
|
||||
|
||||
|
||||
|
|
1
apps/admin-x-demo/.eslintignore
Normal file
|
@ -0,0 +1 @@
|
|||
tailwind.config.cjs
|
56
apps/admin-x-demo/.eslintrc.cjs
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* eslint-env node */
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'plugin:ghost/ts',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended'
|
||||
],
|
||||
plugins: [
|
||||
'ghost',
|
||||
'react-refresh',
|
||||
'tailwindcss'
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
// sort multiple import lines into alphabetical groups
|
||||
'ghost/sort-imports-es6-autofix/sort-imports-es6': ['error', {
|
||||
memberSyntaxSortOrder: ['none', 'all', 'single', 'multiple']
|
||||
}],
|
||||
|
||||
// TODO: re-enable this (maybe fixed fast refresh?)
|
||||
'react-refresh/only-export-components': 'off',
|
||||
|
||||
// suppress errors for missing 'import React' in JSX files, as we don't need it
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
// ignore prop-types for now
|
||||
'react/prop-types': 'off',
|
||||
|
||||
// TODO: re-enable these if deemed useful
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
|
||||
// custom react rules
|
||||
'react/jsx-sort-props': ['error', {
|
||||
reservedFirst: true,
|
||||
callbacksLast: true,
|
||||
shorthandLast: true,
|
||||
locale: 'en'
|
||||
}],
|
||||
'react/button-has-type': 'error',
|
||||
'react/no-array-index-key': 'error',
|
||||
'react/jsx-key': 'off',
|
||||
|
||||
'tailwindcss/classnames-order': ['error', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/enforces-negative-arbitrary-values': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/enforces-shorthand': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/migration-from-tailwind-2': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/no-arbitrary-value': 'off',
|
||||
'tailwindcss/no-custom-classname': 'off',
|
||||
'tailwindcss/no-contradicting-classname': ['error', {config: 'tailwind.config.cjs'}]
|
||||
}
|
||||
};
|
3
apps/admin-x-demo/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
dist
|
||||
playwright-report
|
||||
test-results
|
13
apps/admin-x-demo/index.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>AdminX Standalone</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/standalone.tsx"></script>
|
||||
</body>
|
||||
</html>
|
71
apps/admin-x-demo/package.json
Normal file
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"name": "@tryghost/admin-x-demo",
|
||||
"version": "0.0.20",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/TryGhost/Ghost/tree/main/apps/admin-x-demo"
|
||||
},
|
||||
"author": "Ghost Foundation",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"dist/"
|
||||
],
|
||||
"main": "./dist/admin-x-demo.umd.cjs",
|
||||
"module": "./dist/admin-x-demo.js",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org/"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite build --watch",
|
||||
"dev:start": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"lint": "yarn run lint:code && yarn run lint:test",
|
||||
"lint:code": "eslint --ext .js,.ts,.cjs,.tsx --cache src",
|
||||
"lint:test": "eslint -c test/.eslintrc.cjs --ext .js,.ts,.cjs,.tsx --cache test",
|
||||
"test:unit": "yarn nx build && vitest run",
|
||||
"test:acceptance": "NODE_OPTIONS='--experimental-specifier-resolution=node --no-warnings' VITE_TEST=true playwright test",
|
||||
"test:acceptance:slowmo": "TIMEOUT=100000 PLAYWRIGHT_SLOWMO=100 yarn test:acceptance --headed",
|
||||
"test:acceptance:full": "ALL_BROWSERS=1 yarn test:acceptance",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "14.1.0",
|
||||
"@tryghost/admin-x-design-system": "0.0.0",
|
||||
"@tryghost/admin-x-framework": "0.0.0",
|
||||
"@types/react": "18.2.41",
|
||||
"@types/react-dom": "18.2.17",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
},
|
||||
"nx": {
|
||||
"targets": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"build",
|
||||
{
|
||||
"projects": [
|
||||
"@tryghost/admin-x-design-system",
|
||||
"@tryghost/admin-x-framework"
|
||||
],
|
||||
"target": "build"
|
||||
}
|
||||
]
|
||||
},
|
||||
"test:acceptance": {
|
||||
"dependsOn": [
|
||||
"test:acceptance",
|
||||
{
|
||||
"projects": [
|
||||
"@tryghost/admin-x-design-system",
|
||||
"@tryghost/admin-x-framework"
|
||||
],
|
||||
"target": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
apps/admin-x-demo/playwright.config.mjs
Normal file
|
@ -0,0 +1,3 @@
|
|||
import adminXPlaywrightConfig from '@tryghost/admin-x-framework/playwright';
|
||||
|
||||
export default adminXPlaywrightConfig();
|
1
apps/admin-x-demo/postcss.config.cjs
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require('@tryghost/admin-x-design-system/postcss.config.cjs');
|
30
apps/admin-x-demo/src/App.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
import MainContent from './MainContent';
|
||||
import {DesignSystemApp, DesignSystemAppProps} from '@tryghost/admin-x-design-system';
|
||||
import {FrameworkProvider, TopLevelFrameworkProps} from '@tryghost/admin-x-framework';
|
||||
import {RoutingProvider} from '@tryghost/admin-x-framework/routing';
|
||||
|
||||
interface AppProps {
|
||||
framework: TopLevelFrameworkProps;
|
||||
designSystem: DesignSystemAppProps;
|
||||
}
|
||||
|
||||
const modals = {
|
||||
paths: {
|
||||
'demo-modal': 'DemoModal'
|
||||
},
|
||||
load: async () => import('./components/modals')
|
||||
};
|
||||
|
||||
const App: React.FC<AppProps> = ({framework, designSystem}) => {
|
||||
return (
|
||||
<FrameworkProvider {...framework}>
|
||||
<RoutingProvider basePath='demo-x' modals={modals}>
|
||||
<DesignSystemApp className='admin-x-demo' {...designSystem}>
|
||||
<MainContent />
|
||||
</DesignSystemApp>
|
||||
</RoutingProvider>
|
||||
</FrameworkProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
147
apps/admin-x-demo/src/DetailPage.tsx
Normal file
|
@ -0,0 +1,147 @@
|
|||
import {Avatar, Breadcrumbs, Button, Heading, Page, Toggle, ViewContainer} from '@tryghost/admin-x-design-system';
|
||||
import {useRouting} from '@tryghost/admin-x-framework/routing';
|
||||
|
||||
const DetailPage: React.FC = () => {
|
||||
const {updateRoute} = useRouting();
|
||||
|
||||
return (
|
||||
<Page
|
||||
breadCrumbs={
|
||||
<Breadcrumbs
|
||||
items={[
|
||||
{
|
||||
label: 'Members',
|
||||
onClick: () => {
|
||||
updateRoute('');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Emerson Vaccaro'
|
||||
}
|
||||
]}
|
||||
onBack={() => {
|
||||
updateRoute('');
|
||||
}}
|
||||
/>
|
||||
}
|
||||
fullBleedPage={false}
|
||||
>
|
||||
<ViewContainer
|
||||
firstOnPage={false}
|
||||
headerContent={
|
||||
<div>
|
||||
<Avatar bgColor='#A5D5F7' image='https://i.pravatar.cc/150' label='EV' labelColor='white' size='2xl' />
|
||||
<Heading className='mt-2' level={1}>Emerson Vaccaro</Heading>
|
||||
<div className=''>Colombus, OH</div>
|
||||
</div>
|
||||
}
|
||||
primaryAction={
|
||||
{
|
||||
icon: 'ellipsis',
|
||||
color: 'outline'
|
||||
}
|
||||
}
|
||||
type='page'
|
||||
>
|
||||
<div className='grid grid-cols-3 border-b border-grey-200 pb-5 tablet:grid-cols-4'>
|
||||
<div className='col-span-3 -ml-5 mb-5 hidden h-full gap-4 px-5 tablet:!visible tablet:col-span-1 tablet:mb-0 tablet:!flex tablet:flex-col tablet:gap-0'>
|
||||
<span>Last seen on <strong>22 June 2023</strong></span>
|
||||
<span className='tablet:mt-2'>Created on <strong>27 Jan 2021</strong></span>
|
||||
</div>
|
||||
<div className='flex h-full flex-col tablet:px-5'>
|
||||
<Heading level={6}>Emails received</Heading>
|
||||
<span className='mt-1 text-4xl font-bold leading-none'>181</span>
|
||||
</div>
|
||||
<div className='flex h-full flex-col tablet:px-5'>
|
||||
<Heading level={6}>Emails opened</Heading>
|
||||
<span className='mt-1 text-4xl font-bold leading-none'>104</span>
|
||||
</div>
|
||||
<div className='-mr-5 flex h-full flex-col tablet:px-5'>
|
||||
<Heading level={6}>Average open rate</Heading>
|
||||
<span className='mt-1 text-4xl font-bold leading-none'>57%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='grid grid-cols-2 items-baseline border-b border-grey-200 py-5 tablet:grid-cols-4'>
|
||||
<div className='-ml-5 flex h-full flex-col gap-6 border-r border-grey-200 px-5'>
|
||||
<div className='flex justify-between'>
|
||||
<Heading level={5}>Member data</Heading>
|
||||
<Button color='green' label='Edit' link />
|
||||
</div>
|
||||
<div>
|
||||
<Heading level={6}>Name</Heading>
|
||||
<div>Emerson Vaccaro</div>
|
||||
</div>
|
||||
<div>
|
||||
<Heading level={6}>Email</Heading>
|
||||
<div>emerson@vaccaro.com</div>
|
||||
</div>
|
||||
<div>
|
||||
<Heading level={6}>Labels</Heading>
|
||||
<div className='mt-2 flex gap-1'>
|
||||
<div className='inline-block rounded-sm bg-grey-200 px-1.5 text-xs font-medium'>VIP</div>
|
||||
<div className='inline-block rounded-sm bg-grey-200 px-1.5 text-xs font-medium'>Inner Circle</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Heading level={6}>Notes</Heading>
|
||||
<div className='text-grey-500'>No notes.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex h-full flex-col gap-6 border-grey-200 px-5 tablet:border-r'>
|
||||
<Heading level={5}>Newsletters</Heading>
|
||||
<div className='flex flex-col gap-3'>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Toggle />
|
||||
<span>Daily news</span>
|
||||
</div>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Toggle />
|
||||
<span>Weekly roundup</span>
|
||||
</div>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Toggle checked />
|
||||
<span>The Inner Circle</span>
|
||||
</div>
|
||||
<div className='mt-5 rounded border border-red p-4 text-sm text-red'>
|
||||
This member cannot receive emails due to permanent failure (bounce).
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='-ml-5 flex h-full flex-col gap-6 border-r border-grey-200 px-5 pt-10 tablet:ml-0 tablet:pt-0'>
|
||||
<Heading level={5}>Subscriptions</Heading>
|
||||
<div className='flex items-center gap-3'>
|
||||
<div className='flex h-16 w-16 flex-col items-center justify-center rounded-md bg-grey-200'>
|
||||
<Heading level={5}>$5</Heading>
|
||||
<span className='text-xs text-grey-700'>Yearly</span>
|
||||
</div>
|
||||
<div className='flex flex-col'>
|
||||
<span className='font-semibold'>Gold</span>
|
||||
<span className='text-sm text-grey-500'>Renews 21 Jan 2024</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='-mr-5 flex h-full flex-col gap-6 px-5 pt-10 tablet:pt-0'>
|
||||
<div className='flex justify-between'>
|
||||
<Heading level={5}>Activity</Heading>
|
||||
<Button color='green' label='View all' link />
|
||||
</div>
|
||||
<div className='flex flex-col text-sm'>
|
||||
<span className='font-semibold'>Logged in</span>
|
||||
<span className='text-sm text-grey-500'>13 days ago</span>
|
||||
</div>
|
||||
<div className='flex flex-col text-sm'>
|
||||
<span className='font-semibold'>Subscribed to Daily News</span>
|
||||
<span className='text-sm text-grey-500'>17 days ago</span>
|
||||
</div>
|
||||
<div className='flex flex-col text-sm'>
|
||||
<span className='font-semibold'>Logged in</span>
|
||||
<span className='text-sm text-grey-500'>21 days ago</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ViewContainer>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default DetailPage;
|
246
apps/admin-x-demo/src/ListPage.tsx
Normal file
|
@ -0,0 +1,246 @@
|
|||
import {Avatar, Button, ButtonGroup, DynamicTable, DynamicTableColumn, DynamicTableRow, Heading, Hint, Page, SortMenu, Tooltip, ViewContainer, showToast} from '@tryghost/admin-x-design-system';
|
||||
import {useRouting} from '@tryghost/admin-x-framework/routing';
|
||||
import {useState} from 'react';
|
||||
|
||||
const ListPage = () => {
|
||||
const {updateRoute} = useRouting();
|
||||
const [view, setView] = useState<string>('list');
|
||||
|
||||
const dummyActions = [
|
||||
<Button label='Filter' onClick={() => {
|
||||
showToast({message: 'Were you really expecting a filter? 😛'});
|
||||
}} />,
|
||||
<SortMenu
|
||||
direction='desc'
|
||||
items={[
|
||||
{
|
||||
id: 'date-added',
|
||||
label: 'Date added',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
label: 'Name'
|
||||
},
|
||||
{
|
||||
id: 'redemptions',
|
||||
label: 'Open Rate'
|
||||
}
|
||||
]}
|
||||
position="left"
|
||||
onDirectionChange={() => {}}
|
||||
onSortChange={() => {}}
|
||||
/>,
|
||||
<Tooltip content="Search members">
|
||||
<Button icon='magnifying-glass' size='sm' onClick={() => {
|
||||
alert('Clicked search');
|
||||
}} />
|
||||
</Tooltip>,
|
||||
<ButtonGroup buttons={[
|
||||
{
|
||||
icon: 'listview',
|
||||
size: 'sm',
|
||||
iconColorClass: (view === 'list' ? 'text-black' : 'text-grey-500'),
|
||||
onClick: () => {
|
||||
setView('list');
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: 'cardview',
|
||||
size: 'sm',
|
||||
iconColorClass: (view === 'card' ? 'text-black' : 'text-grey-500'),
|
||||
onClick: () => {
|
||||
setView('card');
|
||||
}
|
||||
}
|
||||
]} clearBg={false} link />
|
||||
];
|
||||
|
||||
const testColumns: DynamicTableColumn[] = [
|
||||
{
|
||||
title: 'Member',
|
||||
noWrap: true,
|
||||
minWidth: '1%',
|
||||
maxWidth: '1%'
|
||||
},
|
||||
{
|
||||
title: 'Status'
|
||||
},
|
||||
{
|
||||
title: 'Open rate'
|
||||
},
|
||||
{
|
||||
title: 'Location',
|
||||
noWrap: true
|
||||
},
|
||||
{
|
||||
title: 'Created',
|
||||
noWrap: true
|
||||
},
|
||||
{
|
||||
title: 'Signed up on post',
|
||||
noWrap: true,
|
||||
maxWidth: '150px'
|
||||
},
|
||||
{
|
||||
title: 'Newsletter'
|
||||
},
|
||||
{
|
||||
title: 'Billing period'
|
||||
},
|
||||
{
|
||||
title: 'Email sent'
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
hidden: true,
|
||||
disableRowClick: true
|
||||
}
|
||||
];
|
||||
|
||||
const testRows = (noOfRows: number) => {
|
||||
const data: DynamicTableRow[] = [];
|
||||
for (let i = 0; i < noOfRows; i++) {
|
||||
data.push(
|
||||
{
|
||||
onClick: () => {
|
||||
updateRoute('detail');
|
||||
},
|
||||
cells: [
|
||||
(<div className='flex items-center gap-3 whitespace-nowrap pr-10'>
|
||||
<Avatar image={`https://i.pravatar.cc/150?img=${i}`} />
|
||||
<div>
|
||||
{i % 3 === 0 && <div className='whitespace-nowrap text-md'>Jamie Larson</div>}
|
||||
{i % 3 === 1 && <div className='whitespace-nowrap text-md'>Giana Septimus</div>}
|
||||
{i % 3 === 2 && <div className='whitespace-nowrap text-md'>Zaire Bator</div>}
|
||||
<div className='text-grey-700'>jamie@larson.com</div>
|
||||
</div>
|
||||
</div>),
|
||||
'Free',
|
||||
'40%',
|
||||
'London, UK',
|
||||
<div>
|
||||
<div>22 June 2023</div>
|
||||
<div className='text-grey-500'>5 months ago</div>
|
||||
</div>,
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
|
||||
'Subscribed',
|
||||
'Monthly',
|
||||
'1,303',
|
||||
<Button color='green' label='Edit' link onClick={() => {
|
||||
alert('Clicked Edit in row:' + i);
|
||||
}} />
|
||||
]
|
||||
}
|
||||
);
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
const dummyCards = (noOfCards: number) => {
|
||||
const cards = [];
|
||||
|
||||
for (let i = 0; i < noOfCards; i++) {
|
||||
cards.push(
|
||||
<div className='flex min-h-[20vh] cursor-pointer flex-col items-center gap-5 rounded-sm bg-grey-100 p-7 pt-9 transition-all hover:bg-grey-200' onClick={() => {
|
||||
updateRoute('detail');
|
||||
}}>
|
||||
<Avatar image={`https://i.pravatar.cc/150?img=${i}`} size='xl' />
|
||||
<div className='flex flex-col items-center'>
|
||||
<Heading level={5}>
|
||||
{i % 3 === 0 && 'Jamie Larson'}
|
||||
{i % 3 === 1 && 'Giana Septimus'}
|
||||
{i % 3 === 2 && 'Zaire Bator'}
|
||||
</Heading>
|
||||
<div className='mt-1 text-sm text-grey-700'>
|
||||
{i % 3 === 0 && 'jamie@larson.com'}
|
||||
{i % 3 === 1 && 'giana@septimus.com'}
|
||||
{i % 3 === 2 && 'zaire@bator.com'}
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex w-full flex-col gap-4 border-t border-grey-300 pt-5'>
|
||||
{i % 3 === 0 && (<>
|
||||
<div className='flex gap-4'>
|
||||
<div className='basis-1/2 text-center'>
|
||||
<Heading level={6}>Open rate</Heading>
|
||||
<div className='text-lg'>83%</div>
|
||||
</div>
|
||||
<div className='basis-1/2 text-center'>
|
||||
<Heading level={6}>Click rate</Heading>
|
||||
<div className='text-lg'>19%</div>
|
||||
</div>
|
||||
</div>
|
||||
</>)}
|
||||
{i % 3 === 1 && (<>
|
||||
<div className='flex gap-4'>
|
||||
<div className='basis-1/2 text-center'>
|
||||
<Heading level={6}>Open rate</Heading>
|
||||
<div className='text-lg'>68%</div>
|
||||
</div>
|
||||
<div className='basis-1/2 text-center'>
|
||||
<Heading level={6}>Click rate</Heading>
|
||||
<div className='text-lg'>21%</div>
|
||||
</div>
|
||||
</div>
|
||||
</>)}
|
||||
{i % 3 === 2 && (<>
|
||||
<div className='flex gap-4'>
|
||||
<div className='basis-1/2 text-center'>
|
||||
<Heading level={6}>Open rate</Heading>
|
||||
<div className='text-lg'>89%</div>
|
||||
</div>
|
||||
<div className='basis-1/2 text-center'>
|
||||
<Heading level={6}>Click rate</Heading>
|
||||
<div className='text-lg'>34%</div>
|
||||
</div>
|
||||
</div>
|
||||
</>)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return cards;
|
||||
};
|
||||
|
||||
let contents = <></>;
|
||||
switch (view) {
|
||||
case 'list':
|
||||
contents = <DynamicTable
|
||||
cellClassName='text-sm'
|
||||
columns={testColumns}
|
||||
footer={
|
||||
<Hint>30 members</Hint>
|
||||
}
|
||||
rows={testRows(30)}
|
||||
stickyFooter
|
||||
stickyHeader
|
||||
/>;
|
||||
break;
|
||||
case 'card':
|
||||
contents = <div className='grid grid-cols-4 gap-8 py-8'>{dummyCards(30)}</div>;
|
||||
break;
|
||||
}
|
||||
|
||||
const demoPage = (
|
||||
<Page>
|
||||
<ViewContainer
|
||||
actions={dummyActions}
|
||||
primaryAction={{
|
||||
title: 'About',
|
||||
onClick: () => {
|
||||
updateRoute('demo-modal');
|
||||
}
|
||||
}}
|
||||
title='AdminX Demo App'
|
||||
toolbarBorder={view === 'card'}
|
||||
type='page'
|
||||
>
|
||||
{contents}
|
||||
</ViewContainer>
|
||||
</Page>
|
||||
);
|
||||
|
||||
return demoPage;
|
||||
};
|
||||
|
||||
export default ListPage;
|
15
apps/admin-x-demo/src/MainContent.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
import DetailPage from './DetailPage';
|
||||
import ListPage from './ListPage';
|
||||
import {useRouting} from '@tryghost/admin-x-framework/routing';
|
||||
|
||||
const MainContent = () => {
|
||||
const {route} = useRouting();
|
||||
|
||||
if (route === 'detail') {
|
||||
return <DetailPage />;
|
||||
} else {
|
||||
return <ListPage />;
|
||||
}
|
||||
};
|
||||
|
||||
export default MainContent;
|
33
apps/admin-x-demo/src/components/DemoModal.tsx
Normal file
|
@ -0,0 +1,33 @@
|
|||
import NiceModal from '@ebay/nice-modal-react';
|
||||
import {Heading, Modal} from '@tryghost/admin-x-design-system';
|
||||
import {useRouting} from '@tryghost/admin-x-framework/routing';
|
||||
|
||||
const DemoModal = NiceModal.create(() => {
|
||||
const {updateRoute} = useRouting();
|
||||
const modal = NiceModal.useModal();
|
||||
|
||||
return (
|
||||
<Modal
|
||||
afterClose={() => {
|
||||
updateRoute('');
|
||||
}}
|
||||
cancelLabel=''
|
||||
okLabel='Close'
|
||||
size='sm'
|
||||
title='About'
|
||||
onOk={() => {
|
||||
updateRoute('');
|
||||
modal.remove();
|
||||
}}
|
||||
>
|
||||
<div className='mt-3 flex flex-col gap-4'>
|
||||
<p>{`You're looking at a React app inside Ghost Admin. It uses common AdminX framework and Design System packages, and works seamlessly with the current Admin's routing.`}</p>
|
||||
<p>{`At the moment the look and feel follows the current Admin's style to blend in with existing pages. However the system is built in a very flexible way to allow easy updates in the future.`}</p>
|
||||
<Heading className='-mb-2 mt-4' level={5}>Contents</Heading>
|
||||
<p>{`The demo uses a mocked list of members — it's `}<strong>not</strong> {`the actual or future design of members in Ghost Admin. Instead, the pages showcase common design patterns like a list and detail, navigation, modals and toasts.`}</p>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
});
|
||||
|
||||
export default DemoModal;
|
9
apps/admin-x-demo/src/components/modals.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
import DemoModal from './DemoModal';
|
||||
import {ModalComponent} from '@tryghost/admin-x-framework/routing';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const modals = {DemoModal} satisfies {[key: string]: ModalComponent<any>};
|
||||
|
||||
export default modals;
|
||||
|
||||
export type ModalName = keyof typeof modals;
|
6
apps/admin-x-demo/src/index.tsx
Normal file
|
@ -0,0 +1,6 @@
|
|||
import './styles/index.css';
|
||||
import App from './App.tsx';
|
||||
|
||||
export {
|
||||
App as AdminXApp
|
||||
};
|
5
apps/admin-x-demo/src/standalone.tsx
Normal file
|
@ -0,0 +1,5 @@
|
|||
import './styles/index.css';
|
||||
import App from './App.tsx';
|
||||
import renderStandaloneApp from '@tryghost/admin-x-framework/test/render';
|
||||
|
||||
renderStandaloneApp(App, {});
|
1
apps/admin-x-demo/src/styles/index.css
Normal file
|
@ -0,0 +1 @@
|
|||
@import '@tryghost/admin-x-design-system/styles.css';
|
6
apps/admin-x-demo/tailwind.config.cjs
Normal file
|
@ -0,0 +1,6 @@
|
|||
const adminXPreset = require('@tryghost/admin-x-design-system/tailwind.cjs');
|
||||
|
||||
module.exports = {
|
||||
presets: [adminXPreset('.admin-x-demo')],
|
||||
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}', '../../node_modules/@tryghost/admin-x-design-system/es/**/*.{js,ts,jsx,tsx}']
|
||||
};
|
6
apps/admin-x-demo/test/.eslintrc.cjs
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
plugins: ['ghost'],
|
||||
extends: [
|
||||
'plugin:ghost/ts-test'
|
||||
]
|
||||
};
|
18
apps/admin-x-demo/test/acceptance/example.test.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import {expect, test} from '@playwright/test';
|
||||
import {mockApi, responseFixtures} from '@tryghost/admin-x-framework/test/acceptance';
|
||||
|
||||
test.describe('Demo', async () => {
|
||||
test('Renders the list page', async ({page}) => {
|
||||
await mockApi({page, requests: {
|
||||
browseSettings: {
|
||||
method: 'GET',
|
||||
path: /^\/settings\/\?group=/,
|
||||
response: responseFixtures.settings
|
||||
}
|
||||
}});
|
||||
|
||||
await page.goto('/');
|
||||
|
||||
await expect(page.locator('body')).toContainText('AdminX Demo App');
|
||||
});
|
||||
});
|
10
apps/admin-x-demo/test/unit/example.test.tsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
import ListPage from '../../src/ListPage';
|
||||
import {render, screen} from '@testing-library/react';
|
||||
|
||||
describe('Demo', function () {
|
||||
it('renders a component', async function () {
|
||||
render(<ListPage />);
|
||||
|
||||
expect(screen.getAllByRole('heading')[0].textContent).toEqual('AdminX Demo App');
|
||||
});
|
||||
});
|
23
apps/admin-x-demo/tsconfig.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src", "test"]
|
||||
}
|
10
apps/admin-x-demo/vite.config.mjs
Normal file
|
@ -0,0 +1,10 @@
|
|||
import adminXViteConfig from '@tryghost/admin-x-framework/vite';
|
||||
import pkg from './package.json';
|
||||
import {resolve} from 'path';
|
||||
|
||||
export default (function viteConfig() {
|
||||
return adminXViteConfig({
|
||||
packageName: pkg.name,
|
||||
entry: resolve(__dirname, 'src/index.tsx')
|
||||
});
|
||||
});
|
41
apps/admin-x-design-system/.eslintrc.cjs
Normal file
|
@ -0,0 +1,41 @@
|
|||
module.exports = {
|
||||
extends: [
|
||||
'plugin:ghost/ts',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended'
|
||||
],
|
||||
plugins: [
|
||||
'ghost',
|
||||
'react-refresh',
|
||||
'tailwindcss'
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
// suppress errors for missing 'import React' in JSX files, as we don't need it
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
// ignore prop-types for now
|
||||
'react/prop-types': 'off',
|
||||
|
||||
'react/jsx-sort-props': ['error', {
|
||||
reservedFirst: true,
|
||||
callbacksLast: true,
|
||||
shorthandLast: true,
|
||||
locale: 'en'
|
||||
}],
|
||||
'react/button-has-type': 'error',
|
||||
'react/no-array-index-key': 'error',
|
||||
'react/jsx-key': 'off',
|
||||
|
||||
'tailwindcss/classnames-order': ['error', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/enforces-negative-arbitrary-values': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/enforces-shorthand': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/migration-from-tailwind-2': ['warn', {config: 'tailwind.config.cjs'}],
|
||||
'tailwindcss/no-arbitrary-value': 'off',
|
||||
'tailwindcss/no-custom-classname': 'off',
|
||||
'tailwindcss/no-contradicting-classname': ['error', {config: 'tailwind.config.cjs'}]
|
||||
}
|
||||
};
|
2
apps/admin-x-design-system/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
es
|
||||
types
|
38
apps/admin-x-design-system/.storybook/adminx-theme.tsx
Normal file
|
@ -0,0 +1,38 @@
|
|||
import {create} from '@storybook/theming/create';
|
||||
|
||||
export default create({
|
||||
base: 'light',
|
||||
// Typography
|
||||
fontBase: '"Inter", sans-serif',
|
||||
fontCode: 'monospace',
|
||||
|
||||
brandTitle: 'AdminX Design System',
|
||||
brandUrl: 'https://ghost.org',
|
||||
brandImage: 'https://github.com/peterzimon/playground/assets/353959/c4358b4e-232f-4dba-8abb-adb3142ccd89',
|
||||
brandTarget: '_self',
|
||||
|
||||
//
|
||||
colorPrimary: '#30CF43',
|
||||
colorSecondary: '#15171A',
|
||||
|
||||
// UI
|
||||
appBg: '#ffffff',
|
||||
appContentBg: '#ffffff',
|
||||
appBorderColor: '#EBEEF0',
|
||||
appBorderRadius: 0,
|
||||
|
||||
// Text colors
|
||||
textColor: '#15171A',
|
||||
textInverseColor: '#ffffff',
|
||||
|
||||
// Toolbar default and active colors
|
||||
barTextColor: '#9E9E9E',
|
||||
barSelectedColor: '#15171A',
|
||||
barBg: '#ffffff',
|
||||
|
||||
// Form colors
|
||||
inputBg: '#ffffff',
|
||||
inputBorder: '#15171A',
|
||||
inputTextColor: '#15171A',
|
||||
inputBorderRadius: 2,
|
||||
});
|
27
apps/admin-x-design-system/.storybook/main.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
import type { StorybookConfig } from "@storybook/react-vite";
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-interactions",
|
||||
{
|
||||
name: '@storybook/addon-styling',
|
||||
},
|
||||
],
|
||||
framework: {
|
||||
name: "@storybook/react-vite",
|
||||
options: {},
|
||||
},
|
||||
docs: {
|
||||
autodocs: "tag",
|
||||
},
|
||||
async viteFinal(config, options) {
|
||||
config.resolve!.alias = {
|
||||
crypto: require.resolve('rollup-plugin-node-builtins')
|
||||
}
|
||||
return config;
|
||||
}
|
||||
};
|
||||
export default config;
|
6
apps/admin-x-design-system/.storybook/manager.tsx
Normal file
|
@ -0,0 +1,6 @@
|
|||
import {addons} from '@storybook/manager-api';
|
||||
import adminxTheme from './adminx-theme';
|
||||
|
||||
addons.setConfig({
|
||||
theme: adminxTheme
|
||||
});
|
107
apps/admin-x-design-system/.storybook/preview.tsx
Normal file
|
@ -0,0 +1,107 @@
|
|||
import React from 'react';
|
||||
|
||||
import '../styles.css';
|
||||
import './storybook.css';
|
||||
|
||||
import type { Preview } from "@storybook/react";
|
||||
import DesignSystemProvider from '../src/providers/DesignSystemProvider';
|
||||
import adminxTheme from './adminx-theme';
|
||||
|
||||
// import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport';
|
||||
|
||||
const customViewports = {
|
||||
sm: {
|
||||
name: 'sm',
|
||||
styles: {
|
||||
width: '480px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
md: {
|
||||
name: 'md',
|
||||
styles: {
|
||||
width: '640px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
lg: {
|
||||
name: 'lg',
|
||||
styles: {
|
||||
width: '1024px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
xl: {
|
||||
name: 'xl',
|
||||
styles: {
|
||||
width: '1320px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
tablet: {
|
||||
name: 'tablet',
|
||||
styles: {
|
||||
width: '860px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
options: {
|
||||
storySort: {
|
||||
method: 'alphabetical',
|
||||
order: ['Welcome', 'Foundations', ['Style Guide', 'Colors', 'Icons', 'ErrorHandling'], 'Global', ['Form', 'Chrome', 'Modal', 'Layout', ['View Container', 'Page Header', 'Page'], 'List', 'Table', '*'], 'Settings', ['Setting Section', 'Setting Group', '*'], 'Experimental'],
|
||||
},
|
||||
},
|
||||
docs: {
|
||||
theme: adminxTheme,
|
||||
},
|
||||
viewport: {
|
||||
viewports: {
|
||||
...customViewports,
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
(Story, context) => {
|
||||
let {scheme} = context.globals;
|
||||
|
||||
return (
|
||||
<div className={`admin-x-design-system admin-x-base ${scheme === 'dark' ? 'dark' : ''}`} style={{
|
||||
// padding: '24px',
|
||||
// width: 'unset',
|
||||
height: 'unset',
|
||||
// overflow: 'unset',
|
||||
background: (scheme === 'dark' ? '#131416' : '')
|
||||
}}>
|
||||
{/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it */}
|
||||
<DesignSystemProvider fetchKoenigLexical={async () => {}}>
|
||||
<Story />
|
||||
</DesignSystemProvider>
|
||||
</div>);
|
||||
},
|
||||
],
|
||||
globalTypes: {
|
||||
scheme: {
|
||||
name: "Scheme",
|
||||
description: "Select light or dark mode",
|
||||
defaultValue: "light",
|
||||
toolbar: {
|
||||
icon: "mirror",
|
||||
items: ["light", "dark"],
|
||||
dynamicTitle: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default preview;
|
247
apps/admin-x-design-system/.storybook/storybook.css
Normal file
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* We load Inter in Ember admin, so loading it explicitly here makes the final rendering
|
||||
* in Storybook match the final rendering when embedded in Ember
|
||||
*/
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
src: url("./Inter.ttf") format("truetype-variations");
|
||||
font-weight: 100 900;
|
||||
}
|
||||
|
||||
:root {
|
||||
font-size: 62.5%;
|
||||
line-height: 1.5;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
html, body, #root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
letter-spacing: unset;
|
||||
}
|
||||
|
||||
.sbdocs-wrapper {
|
||||
padding: 3vmin !important;
|
||||
}
|
||||
|
||||
.sbdocs-wrapper .sbdocs-content {
|
||||
max-width: 1320px;
|
||||
}
|
||||
|
||||
.sb-doc {
|
||||
max-width: 740px;
|
||||
width: 100%;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.sb-doc,
|
||||
.sb-doc a,
|
||||
.sb-doc h1,
|
||||
.sb-doc h2,
|
||||
.sb-doc h3,
|
||||
.sb-doc h4,
|
||||
.sb-doc h5,
|
||||
.sb-doc h6,
|
||||
.sb-doc p,
|
||||
.sb-doc ul li,
|
||||
.sbdocs-title,
|
||||
.sb-doc ol li {
|
||||
font-family: Inter, sans-serif !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.sb-doc a {
|
||||
color: #30CF43;
|
||||
}
|
||||
|
||||
.sb-doc h1 {
|
||||
font-size: 48px !important;
|
||||
letter-spacing: -0.04em !important;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.sb-doc h2 {
|
||||
margin-top: 40px !important;
|
||||
font-size: 27px;
|
||||
border: none;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.sb-doc h3 {
|
||||
margin-top: 40px !important;
|
||||
margin-bottom: 4px !important;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.sb-doc h4 {
|
||||
margin: 0 0 4px !important;
|
||||
}
|
||||
|
||||
.sb-doc p,
|
||||
.sb-doc div,
|
||||
.sb-doc ul li,
|
||||
.sb-doc ol li {
|
||||
font-size: 15px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.sb-doc ul li,
|
||||
.sb-doc ol li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sb-doc h2 + p,
|
||||
.sb-doc h3 + p {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.sb-doc img,
|
||||
.sb-wide img {
|
||||
margin-top: 40px !important;
|
||||
margin-bottom: 40px !important;
|
||||
}
|
||||
|
||||
.sb-doc img.small {
|
||||
max-width: 520px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sb-doc p.excerpt {
|
||||
font-size: 19px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.sb-doc .highlight {
|
||||
padding: 12px 20px;
|
||||
border-radius: 4px;
|
||||
background: #EBEEF0;
|
||||
}
|
||||
|
||||
.sb-doc .highlight.purple {
|
||||
background: #F0E9FA;
|
||||
}
|
||||
|
||||
.sb-doc .highlight.purple a {
|
||||
color: #8E42FF;
|
||||
}
|
||||
|
||||
/* Welcome */
|
||||
.sb-doc img.main-image {
|
||||
margin-top: -2vmin !important;
|
||||
margin-left: -44px;
|
||||
margin-right: -32px;
|
||||
margin-bottom: 0 !important;
|
||||
max-width: unset;
|
||||
width: calc(100% + 64px);
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
margin: 32px 0 80px;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container div {
|
||||
flex-basis: 33%;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container div p {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container img {
|
||||
margin: 12px 0 !important;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container div h4 {
|
||||
border-bottom: 1px solid #EBEEF0;
|
||||
padding-bottom: 8px !important;
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container div p {
|
||||
margin: 0;
|
||||
font-size: 13.5px;
|
||||
}
|
||||
|
||||
/* Colors */
|
||||
.color-grid {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.color-grid div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #EBEEF0;
|
||||
}
|
||||
|
||||
.color-grid .swatch {
|
||||
display: block;
|
||||
background: #EFEFEF;
|
||||
border-radius: 100%;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.swatch.green {
|
||||
background: #30CF43;
|
||||
}
|
||||
|
||||
.swatch.black {
|
||||
background: #15171A;
|
||||
}
|
||||
|
||||
.swatch.white {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #EBEEF0;
|
||||
}
|
||||
|
||||
.swatch.lime {
|
||||
background: #B5FF18;
|
||||
}
|
||||
.swatch.blue {
|
||||
background: #14B8FF;
|
||||
}
|
||||
.swatch.purple {
|
||||
background: #8E42FF;
|
||||
}
|
||||
.swatch.pink {
|
||||
background: #FB2D8D;
|
||||
}
|
||||
.swatch.yellow {
|
||||
background: #FFB41F;
|
||||
}
|
||||
.swatch.red {
|
||||
background: #F50B23;
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
|
||||
.sb-doc .streamline {
|
||||
display: grid;
|
||||
grid-template-columns: auto 240px;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.sbdocs-a {
|
||||
color: #30CF43 !important;
|
||||
}
|
23
apps/admin-x-design-system/README.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Admin X Design
|
||||
|
||||
Components, design guidelines and documentation for building apps in Ghost Admin
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
## Develop
|
||||
|
||||
This is a monorepo package.
|
||||
|
||||
Follow the instructions for the top-level repo.
|
||||
1. `git clone` this repo & `cd` into it as usual
|
||||
2. Run `yarn` to install top-level dependencies.
|
||||
|
||||
|
||||
|
||||
## Test
|
||||
|
||||
- `yarn lint` run just eslint
|
||||
- `yarn test` run lint and tests
|
||||
|
76
apps/admin-x-design-system/package.json
Normal file
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"name": "@tryghost/admin-x-design-system",
|
||||
"type": "module",
|
||||
"version": "0.0.0",
|
||||
"repository": "https://github.com/TryGhost/Ghost/tree/main/packages/admin-x-design-system",
|
||||
"author": "Ghost Foundation",
|
||||
"private": true,
|
||||
"main": "es/index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"build": "vite build && tsc -p tsconfig.declaration.json",
|
||||
"prepare": "yarn build",
|
||||
"test": "yarn test:types",
|
||||
"test:types": "tsc --noEmit",
|
||||
"lint:code": "eslint --ext .js,.ts,.cjs,.tsx src/ --cache",
|
||||
"lint": "yarn lint:code && yarn lint:test",
|
||||
"lint:test": "eslint -c test/.eslintrc.cjs --ext .js,.ts,.cjs,.tsx test/ --cache",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build"
|
||||
},
|
||||
"files": [
|
||||
"es",
|
||||
"types",
|
||||
"tailwind.cjs",
|
||||
"tailwind.config.cjs"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@codemirror/lang-html": "^6.4.5",
|
||||
"@storybook/addon-essentials": "7.5.3",
|
||||
"@storybook/addon-interactions": "7.5.3",
|
||||
"@storybook/addon-links": "7.5.3",
|
||||
"@storybook/addon-styling": "1.3.7",
|
||||
"@storybook/blocks": "7.5.3",
|
||||
"@storybook/react": "7.5.3",
|
||||
"@storybook/react-vite": "7.5.3",
|
||||
"@storybook/testing-library": "0.2.2",
|
||||
"@testing-library/react": "14.1.0",
|
||||
"@vitejs/plugin-react": "4.2.0",
|
||||
"c8": "8.0.1",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"eslint-plugin-react-refresh": "0.4.3",
|
||||
"eslint-plugin-tailwindcss": "3.13.0",
|
||||
"mocha": "10.2.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"rollup-plugin-node-builtins": "2.1.2",
|
||||
"sinon": "17.0.0",
|
||||
"storybook": "7.5.3",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "5.3.2",
|
||||
"vite": "4.5.1",
|
||||
"vite-plugin-svgr": "3.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "6.1.0",
|
||||
"@dnd-kit/sortable": "7.0.2",
|
||||
"@ebay/nice-modal-react": "1.2.13",
|
||||
"@sentry/react": "7.84.0",
|
||||
"@tailwindcss/forms": "0.5.7",
|
||||
"@tailwindcss/line-clamp": "0.4.4",
|
||||
"@uiw/react-codemirror": "^4.21.9",
|
||||
"autoprefixer": "10.4.16",
|
||||
"clsx": "2.0.0",
|
||||
"postcss": "8.4.32",
|
||||
"postcss-import": "15.1.0",
|
||||
"react-colorful": "^5.1.2",
|
||||
"react-hot-toast": "2.4.1",
|
||||
"react-select": "5.8.0",
|
||||
"tailwindcss": "3.3.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
}
|
8
apps/admin-x-design-system/postcss.config.cjs
Normal file
|
@ -0,0 +1,8 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-import': {},
|
||||
'tailwindcss/nesting': {},
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
};
|
381
apps/admin-x-design-system/preflight.css
Normal file
|
@ -0,0 +1,381 @@
|
|||
.admin-x-base {
|
||||
/*
|
||||
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
||||
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
||||
*/
|
||||
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box; /* 1 */
|
||||
max-width: revert;
|
||||
max-height: revert;
|
||||
min-width: revert;
|
||||
min-height: revert;
|
||||
border-width: 0; /* 2 */
|
||||
border-style: solid; /* 2 */
|
||||
border-color: theme('borderColor.DEFAULT', currentColor); /* 2 */
|
||||
}
|
||||
|
||||
::before,
|
||||
::after {
|
||||
--tw-content: '';
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use a consistent sensible line-height in all browsers.
|
||||
2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
3. Use a more readable tab size.
|
||||
4. Use the user's configured `sans` font-family by default.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.5; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
-moz-tab-size: 4; /* 3 */
|
||||
tab-size: 4; /* 3 */
|
||||
font-family: theme('fontFamily.sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); /* 4 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove the margin in all browsers.
|
||||
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0; /* 1 */
|
||||
line-height: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Add the correct height in Firefox.
|
||||
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
||||
3. Ensure horizontal rules are visible by default.
|
||||
*/
|
||||
|
||||
hr {
|
||||
height: 0; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
border-top-width: 1px; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct text decoration in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
abbr:where([title]) {
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the default font size and weight for headings.
|
||||
*/
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Reset links to optimize for opt-in styling instead of opt-out.
|
||||
*/
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font weight in Edge and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use the user's configured `mono` font family by default.
|
||||
2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp,
|
||||
pre {
|
||||
font-family: theme('fontFamily.mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
||||
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
||||
3. Remove gaps between table borders by default.
|
||||
*/
|
||||
|
||||
table {
|
||||
text-indent: 0; /* 1 */
|
||||
border-color: inherit; /* 2 */
|
||||
border-collapse: collapse; /* 3 */
|
||||
margin: 0;
|
||||
width: auto;
|
||||
max-width: auto;
|
||||
}
|
||||
|
||||
table td, table th {
|
||||
padding: unset;
|
||||
vertical-align: middle;
|
||||
text-align: left;
|
||||
line-height: auto;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Change the font styles in all browsers.
|
||||
2. Remove the margin in Firefox and Safari.
|
||||
3. Remove default padding in all browsers.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
font-weight: inherit; /* 1 */
|
||||
line-height: inherit; /* 1 */
|
||||
color: inherit; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
padding: 0; /* 3 */
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inheritance of text transform in Edge and Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
letter-spacing: inherit;
|
||||
border-radius: inherit;
|
||||
appearance: auto;
|
||||
-webkit-appearance: auto;
|
||||
background: unset;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Remove default button styles.
|
||||
*/
|
||||
|
||||
button,
|
||||
/* [type='button'], */
|
||||
[type='reset'],
|
||||
[type='submit'] {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
background-color: transparent; /* 2 */
|
||||
background-image: none; /* 2 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Use the modern Firefox focus style for all focusable elements.
|
||||
*/
|
||||
|
||||
:-moz-focusring {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
||||
*/
|
||||
|
||||
:-moz-ui-invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct vertical alignment in Chrome and Firefox.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/*
|
||||
Correct the cursor style of increment and decrement buttons in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-inner-spin-button,
|
||||
::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the odd appearance in Chrome and Safari.
|
||||
2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type='search'] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct display in Chrome and Safari.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/*
|
||||
Removes the default spacing and border for appropriate elements.
|
||||
*/
|
||||
|
||||
blockquote,
|
||||
dl,
|
||||
dd,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
hr,
|
||||
figure,
|
||||
p,
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: unset;
|
||||
line-height: unset;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent resizing textareas horizontally by default.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
||||
2. Set the default placeholder color to the user's configured gray 400 color.
|
||||
*/
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
opacity: 1; /* 1 */
|
||||
@apply text-grey-500; /* 2 */
|
||||
}
|
||||
|
||||
button:focus-visible,
|
||||
input:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
||||
This can trigger a poorly considered lint error in some tools but is included by design.
|
||||
*/
|
||||
|
||||
img,
|
||||
svg,
|
||||
video,
|
||||
canvas,
|
||||
audio,
|
||||
iframe,
|
||||
embed,
|
||||
object {
|
||||
display: block; /* 1 */
|
||||
vertical-align: middle; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
*/
|
||||
|
||||
img,
|
||||
video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
18
apps/admin-x-design-system/src/Boilerplate.stories.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import type {Meta, StoryObj} from '@storybook/react';
|
||||
|
||||
import BoilerPlate from './Boilerplate';
|
||||
|
||||
const meta = {
|
||||
title: 'Meta / Boilerplate',
|
||||
component: BoilerPlate,
|
||||
tags: ['autodocs']
|
||||
} satisfies Meta<typeof BoilerPlate>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof BoilerPlate>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
children: 'This is a boilerplate component. Use as a basis to create new components.'
|
||||
}
|
||||
};
|
27
apps/admin-x-design-system/src/DesignSystemApp.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import {FetchKoenigLexical} from './global/form/HtmlEditor';
|
||||
import DesignSystemProvider from './providers/DesignSystemProvider';
|
||||
|
||||
export interface DesignSystemAppProps extends React.HTMLProps<HTMLDivElement> {
|
||||
darkMode: boolean;
|
||||
fetchKoenigLexical: FetchKoenigLexical;
|
||||
}
|
||||
|
||||
const DesignSystemApp: React.FC<DesignSystemAppProps> = ({darkMode, fetchKoenigLexical, className, children, ...props}) => {
|
||||
const appClassName = clsx(
|
||||
'admin-x-base',
|
||||
darkMode && 'dark',
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={appClassName} {...props}>
|
||||
<DesignSystemProvider fetchKoenigLexical={fetchKoenigLexical}>
|
||||
{children}
|
||||
</DesignSystemProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DesignSystemApp;
|
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 401 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-0.75 -0.75 24 24" height="24" width="24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M13.341093749999999 17.55496875c2.03146875 -0.408375 3.667125 -2.0639062499999996 4.07615625 -4.14796875 0.40903125 2.0840625 2.0442187499999998 3.73959375 4.07578125 4.14796875m0 0.00234375c-2.0315624999999997 0.408375 -3.667125 2.0639062499999996 -4.07615625 4.14796875 -0.40903125 -2.0840625 -2.0443125 -3.73959375 -4.07578125 -4.14796875" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="m19.54621875 12.32025 0.56521875 -0.56521875c0.53071875 -0.53071875 0.8272499999999999 -1.25146875 0.8236875 -2.00203125l-0.0271875 -5.777896875000001c-0.00721875 -1.5429374999999999 -1.25625 -2.791940625 -2.7991875 -2.799225l-5.778 -0.027290625c-0.7505625 -0.003553125 -1.4713124999999998 0.293034375 -2.00203125 0.82374375L1.32765 10.97353125c-0.732223125 0.7321875 -0.7322203125000001 1.91934375 0.000009375 2.6516249999999997l7.13105625 7.131c0.732234375 0.73228125 1.9194093749999999 0.73228125 2.6516906249999996 0l0.94190625 -0.94190625" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M17.75428125 4.329000000000001c-0.1393125 -0.13935 -0.41803125 -0.139359375 -0.5574375 0 -0.1393125 0.13935 -0.1393125 0.418059375 0 0.557409375" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M17.7553125 4.328221875c0.13940625 0.13935 0.13940625 0.418059375 0 0.55741875 -0.1393125 0.13935 -0.41803125 0.13934062500000002 -0.55734375 -0.000009375" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 364 B After Width: | Height: | Size: 364 B |
Before Width: | Height: | Size: 363 B After Width: | Height: | Size: 363 B |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="m7.152187499999999 4.21875 -6.0375000000000005 6.0365625000000005a1.40625 1.40625 0 0 0 0 1.9884375l6.0375000000000005 6.0375000000000005" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m15.347812499999998 4.21875 6.0375000000000005 6.0365625000000005a1.40625 1.40625 0 0 1 0 1.9884375l-6.0375000000000005 6.0375000000000005" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 608 B |
Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 403 B |
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 402 B |
Before Width: | Height: | Size: 451 B After Width: | Height: | Size: 451 B |
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 450 B |
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 452 B |
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 354 B |
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 354 B |
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 448 B |
1
apps/admin-x-design-system/src/assets/icons/at-sign.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M16.171875 11.25A4.921875 4.921875 0 1 1 11.25 6.328125 4.921875 4.921875 0 0 1 16.171875 11.25Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M16.171875 11.25v2.109375a2.8125 2.8125 0 0 0 5.625 0V11.25a10.5459375 10.5459375 0 1 0 -4.21875 8.4375" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 532 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-0.75 -0.75 24 24" height="24" width="24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M0.9375 20.0625h1.8403125" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M19.723125 20.0625H21.5625" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M15.02625 20.0625h1.8403125" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M10.3303125 20.0625h1.839375" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M5.6343749999999995 20.0625h1.839375" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="m0.9375 16.53 4.790625 -6.511875a3.1565625 3.1565625 0 0 1 3.1753125 -1.2225000000000001l4.685625 0.9590624999999999a3.1565625 3.1565625 0 0 0 3.17625 -1.2215624999999999l4.790625 -6.511875" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
apps/admin-x-design-system/src/assets/icons/bills.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-0.75 -0.75 24 24" height="24" width="24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M17.578125 4.21875H2.109375A1.40625 1.40625 0 0 0 0.703125 5.625v8.4375a1.40625 1.40625 0 0 0 1.40625 1.40625h15.46875a1.40625 1.40625 0 0 0 1.40625 -1.40625V5.625a1.40625 1.40625 0 0 0 -1.40625 -1.40625Z" stroke-width="1.5"></path><path stroke="currentColor" d="M3.8671875 7.734375a0.3515625 0.3515625 0 1 1 0 -0.703125" stroke-width="1.5"></path><path stroke="currentColor" d="M3.8671875 7.734375a0.3515625 0.3515625 0 1 0 0 -0.703125" stroke-width="1.5"></path><path stroke="currentColor" d="M15.8203125 12.65625a0.3515625 0.3515625 0 0 1 0 -0.703125" stroke-width="1.5"></path><path stroke="currentColor" d="M15.8203125 12.65625a0.3515625 0.3515625 0 0 0 0 -0.703125" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M9.84375 12.65625a2.8125 2.8125 0 1 0 0 -5.625 2.8125 2.8125 0 0 0 0 5.625Z" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M21.796875 8.4375v8.4375a1.40625 1.40625 0 0 1 -1.40625 1.40625H4.921875" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M12.1875 21.474375a15.9271875 15.9271875 0 0 1 8.3025 -3.646875 1.5 1.5 0 0 0 1.3040625000000001 -1.4878125V2.2171875a1.5121875 1.5121875 0 0 0 -1.7203125 -1.5A16.009687500000002 16.009687500000002 0 0 0 12.1875 4.3125a1.53375 1.53375 0 0 1 -1.875 0A16.009687500000002 16.009687500000002 0 0 0 2.4234375 0.7190625 1.5121875 1.5121875 0 0 0 0.703125 2.2171875v14.1225a1.5 1.5 0 0 0 1.3040625000000001 1.4878125A15.9271875 15.9271875 0 0 1 10.3125 21.474375a1.5309375 1.5309375 0 0 0 1.875 0Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m11.25 4.629375 0 17.1665625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 851 B |
1
apps/admin-x-design-system/src/assets/icons/brackets.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="m7.152187499999999 4.21875 -6.0375000000000005 6.0365625000000005a1.40625 1.40625 0 0 0 0 1.9884375l6.0375000000000005 6.0375000000000005" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m15.347812499999998 4.21875 6.0375000000000005 6.0365625000000005a1.40625 1.40625 0 0 1 0 1.9884375l-6.0375000000000005 6.0375000000000005" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 608 B |
1
apps/admin-x-design-system/src/assets/icons/cardview.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" height="24" width="24"><defs></defs><title>layout-module-1</title><path d="M2.109375 0.7003125h5.625s1.40625 0 1.40625 1.40625v5.625s0 1.40625 -1.40625 1.40625h-5.625s-1.40625 0 -1.40625 -1.40625v-5.625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M2.109375 13.356562499999999h5.625s1.40625 0 1.40625 1.40625v5.625s0 1.40625 -1.40625 1.40625h-5.625s-1.40625 0 -1.40625 -1.40625v-5.625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M14.765625 0.7003125h5.625s1.40625 0 1.40625 1.40625v5.625s0 1.40625 -1.40625 1.40625h-5.625s-1.40625 0 -1.40625 -1.40625v-5.625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M14.765625 13.356562499999999h5.625s1.40625 0 1.40625 1.40625v5.625s0 1.40625 -1.40625 1.40625h-5.625s-1.40625 0 -1.40625 -1.40625v-5.625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 423 B After Width: | Height: | Size: 423 B |
Before Width: | Height: | Size: 275 B After Width: | Height: | Size: 275 B |
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
Before Width: | Height: | Size: 311 B After Width: | Height: | Size: 311 B |
Before Width: | Height: | Size: 314 B After Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 417 B |
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 502 B After Width: | Height: | Size: 502 B |
1
apps/admin-x-design-system/src/assets/icons/discount.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="m2.109375 20.390625 18.28125 -18.28125Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M14.765625 17.578125a2.8125 2.8125 0 1 0 5.625 0 2.8125 2.8125 0 1 0 -5.625 0Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M2.109375 4.921875a2.8125 2.8125 0 1 0 5.625 0 2.8125 2.8125 0 1 0 -5.625 0Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 645 B |
Before Width: | Height: | Size: 642 B After Width: | Height: | Size: 642 B |
Before Width: | Height: | Size: 388 B After Width: | Height: | Size: 388 B |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M10.546875 16.171875a5.625 5.625 0 1 0 11.25 0 5.625 5.625 0 1 0 -11.25 0Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m18.67875 14.536875 -2.7234374999999997 3.6309375000000004a0.705 0.705 0 0 1 -1.0603125 0.0759375l-1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M7.734375 14.765625h-5.625a1.40625 1.40625 0 0 1 -1.40625 -1.40625v-11.25a1.40625 1.40625 0 0 1 1.40625 -1.40625h16.875a1.40625 1.40625 0 0 1 1.40625 1.40625V8.4375" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m20.0728125 1.21875 -7.635 5.8725000000000005a3.10125 3.10125 0 0 1 -3.781875 0L1.0209375 1.21875" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1,019 B |
1
apps/admin-x-design-system/src/assets/icons/email.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="m1.40625 4.453125 19.6875 0 0 14.0625 -19.6875 0Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m20.7759375 4.96875 -7.635 5.8725000000000005a3.10125 3.10125 0 0 1 -3.781875 0L1.7240625 4.96875" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 479 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" height="24" width="24"><defs></defs><path d="M21.796875 12.421875v5.859375a0.9375 0.9375 0 0 1 -0.9375 0.9375H1.640625a0.9375 0.9375 0 0 1 -0.9375 -0.9375V8.671875a0.9375 0.9375 0 0 1 0.9375 -0.9375H8.4375" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M18.125625 13.300312499999999A5.15625 5.15625 0 1 1 21.5625 8.4375" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M14.6878125 8.4375a1.7184375 1.7184375 0 1 0 3.436875 0 1.7184375 1.7184375 0 1 0 -3.436875 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M18.1246875 8.4375A1.719375 1.719375 0 0 0 21.5625 8.4375" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m4.3706249999999995 10.9378125 0 5.077500000000001" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 347 B |
1
apps/admin-x-design-system/src/assets/icons/facebook.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M16.996875 7.265625h-3.99375V5.475a0.9375 0.9375 0 0 1 0.9375 -1.03125h2.8125v-3.75h-4.059375c-3.684375 0 -4.378125 2.8125 -4.378125 4.55625v2.015625h-2.8125v3.75h2.8125v10.78125h4.6875v-10.78125h3.609375Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 420 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-0.75 -0.75 24 24" height="24" width="24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M6.140625 10.828125c-1.78125 0 -3.28125 1.5 -3.28125 3.28125 0 1.5 0.375 3 1.21875 4.3125l0.65625 1.125c0.84375 1.40625 2.4375 2.25 4.03125 2.25h6.1875c2.625 0 4.6875 -2.0625 4.6875 -4.6875v-6.84375c0 -0.9375 -0.75 -1.6875 -1.6875 -1.6875s-1.6875 0.75 -1.6875 1.6875v-0.9375c0 -0.9375 -0.75 -1.6875 -1.6875 -1.6875s-1.6875 0.75 -1.6875 1.6875v0.28125l0 -0.75c0 -0.9375 -0.75 -1.6875 -1.6875 -1.6875s-1.6875 0.75 -1.6875 1.6875l0 0.215625m0 0.5343749999999999 0 -0.5343749999999999m-3.375 4.753125000000001V2.390625c0 -0.9375 0.75 -1.6875 1.6875 -1.6875s1.6875 0.75 1.6875 1.6875l0 6.684375" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 827 B |
Before Width: | Height: | Size: 587 B After Width: | Height: | Size: 587 B |
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 469 B |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M11.8640625 16.8684375a4.273125 4.273125 0 0 1 -5.6690625 2.041875h0a4.273125 4.273125 0 0 1 -2.041875 -5.6690625l1.2956249999999998 -2.7534375a4.2721875 4.2721875 0 0 1 5.668125 -2.041875h0a4.2590625 4.2590625 0 0 1 2.3540625 2.9915624999999997" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M11.105625 5.7253125a4.273125 4.273125 0 0 1 5.6690625 -2.041875h0a4.273125 4.273125 0 0 1 2.041875 5.668125l-1.2956249999999998 2.7534375a4.273125 4.273125 0 0 1 -5.6690625 2.041875h0a4.2496875 4.2496875 0 0 1 -2.205 -2.4553125000000002" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 815 B |
Before Width: | Height: | Size: 848 B After Width: | Height: | Size: 848 B |
1
apps/admin-x-design-system/src/assets/icons/key.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" height="24" width="24"><g><path d="M12.01875 13.603125 14.399999999999999 11.25l1.65 0.440625a1.4625000000000001 1.4625000000000001 0 0 0 1.415625 -0.440625 1.4812500000000002 1.4812500000000002 0 0 0 0.346875 -1.396875l-0.440625 -1.640625 0.7687499999999999 -0.7125 1.65 0.440625A1.4625000000000001 1.4625000000000001 0 0 0 21.20625 7.5 1.4812500000000002 1.4812500000000002 0 0 0 21.5625 6.1125l-0.440625 -1.640625a2.203125 2.203125 0 0 0 -3.121875 -3.121875l-9.103125 9.13125a5.896875 5.896875 0 1 0 3.121875 3.121875Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M3.99375 16.725a1.78125 1.78125 0 1 0 3.5625 0 1.78125 1.78125 0 1 0 -3.5625 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></g></svg>
|
After Width: | Height: | Size: 904 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-0.75 -0.75 24 24" height="24" width="24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M6.305625 0.703125h9.84375" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M14.743125000000001 7.734375V0.703125h-7.03125v7.03125L1.3959375 17.451562499999998A2.8125 2.8125 0 0 0 3.75 21.796875h14.95125a2.8125 2.8125 0 0 0 2.3578125 -4.3453124999999995L14.743125000000001 7.734375Z" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M4.9696875 11.953125h12.515625" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M13.336875000000001 16.171875h2.8125" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M14.743125000000001 14.765625v2.8125" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M14.743125000000001 3.515625h-2.8125" stroke-width="1.5"></path><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M14.743125000000001 6.328125h-2.8125" stroke-width="1.5"></path><path stroke="currentColor" d="M6.305625 18.6328125a0.3515625 0.3515625 0 0 1 0 -0.703125" stroke-width="1.5"></path><path stroke="currentColor" d="M6.305625 18.6328125a0.3515625 0.3515625 0 0 0 0 -0.703125" stroke-width="1.5"></path><g><path stroke="currentColor" d="M9.118125000000001 15.8203125a0.3515625 0.3515625 0 0 1 0 -0.703125" stroke-width="1.5"></path><path stroke="currentColor" d="M9.118125000000001 15.8203125a0.3515625 0.3515625 0 0 0 0 -0.703125" stroke-width="1.5"></path></g></svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
apps/admin-x-design-system/src/assets/icons/language.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" height="24" width="24"><g><path d="M2.109375 0.703125h8.4375s1.40625 0 1.40625 1.40625v8.4375s0 1.40625 -1.40625 1.40625h-8.4375s-1.40625 0 -1.40625 -1.40625v-8.4375s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M14.765625 10.546875h5.625a1.40625 1.40625 0 0 1 1.40625 1.40625v8.4375a1.40625 1.40625 0 0 1 -1.40625 1.40625h-8.4375a1.40625 1.40625 0 0 1 -1.40625 -1.40625v-5.625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m14.53125 16.875 3.28125 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><g><path d="m6.328125 3.515625 0 1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m3.515625 4.921875 5.625 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M7.734375 4.921875s-1.40625 4.21875 -4.21875 4.21875" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M6.328125 7.5a3.675 3.675 0 0 0 2.8125 1.621875" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></g><path d="M14.53125 18.984375v-3.75a1.640625 1.640625 0 0 1 3.28125 0v3.75" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></g></svg>
|
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 636 B After Width: | Height: | Size: 636 B |
1
apps/admin-x-design-system/src/assets/icons/layer.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M21.478125 6.5184375 11.90625 1.5675a1.4465625 1.4465625 0 0 0 -1.3275 0L1.00875 6.5184375a0.5765625 0.5765625 0 0 0 0 1.025625l9.5709375 4.950937499999999a1.4465625 1.4465625 0 0 0 1.3275 0L21.478125 7.544062500000001a0.5775 0.5775 0 0 0 0 -1.025625Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m0.7106250000000001 11.953125 9.8690625 4.760625a1.4465625 1.4465625 0 0 0 1.3275 0l9.897187500000001 -4.760625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m0.7106250000000001 16.171875 9.8690625 4.760625a1.4465625 1.4465625 0 0 0 1.3275 0l9.897187500000001 -4.760625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 924 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" height="24" width="24"><defs></defs><title>layout-headline</title><path d="M2.109375 0.7003125h18.28125s1.40625 0 1.40625 1.40625v1.40625s0 1.40625 -1.40625 1.40625H2.109375s-1.40625 0 -1.40625 -1.40625v-1.40625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M2.109375 9.137812499999999h18.28125s1.40625 0 1.40625 1.40625v1.40625s0 1.40625 -1.40625 1.40625H2.109375s-1.40625 0 -1.40625 -1.40625v-1.40625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M2.109375 17.5753125h18.28125s1.40625 0 1.40625 1.40625v1.40625s0 1.40625 -1.40625 1.40625H2.109375s-1.40625 0 -1.40625 -1.40625v-1.40625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 995 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" height="24" width="24"><defs></defs><title>layout-module-1</title><path d="M2.109375 0.7003125h5.625s1.40625 0 1.40625 1.40625v5.625s0 1.40625 -1.40625 1.40625h-5.625s-1.40625 0 -1.40625 -1.40625v-5.625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M2.109375 13.356562499999999h5.625s1.40625 0 1.40625 1.40625v5.625s0 1.40625 -1.40625 1.40625h-5.625s-1.40625 0 -1.40625 -1.40625v-5.625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M14.765625 0.7003125h5.625s1.40625 0 1.40625 1.40625v5.625s0 1.40625 -1.40625 1.40625h-5.625s-1.40625 0 -1.40625 -1.40625v-5.625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M14.765625 13.356562499999999h5.625s1.40625 0 1.40625 1.40625v5.625s0 1.40625 -1.40625 1.40625h-5.625s-1.40625 0 -1.40625 -1.40625v-5.625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
1
apps/admin-x-design-system/src/assets/icons/like.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="-0.75 -0.75 24 24" height="24" width="24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M0.78375 9.6103125h1.3031249999999999c1.966875 0 3.855 -0.0684375 5.257499999999999 -1.4465625a7.5 7.5 0 0 0 2.2424999999999997 -5.2190625c0 -3.1734375 4.010624999999999 -1.6875 4.010624999999999 1.14375v3.646875a1.875 1.875 0 0 0 1.875 1.875h4.414687499999999c0.9806250000000001 0 1.8046875 0.7565625 1.8234375 1.7371874999999999 0.061875 3.1275 -0.459375 5.4028125 -1.7240625 7.824375 -0.729375 1.396875 -2.2434374999999998 2.175 -3.8184375000000004 2.1403125C5.2228125 21.065624999999997 6.6384375 19.21875 0.78375 19.21875" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 741 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
1
apps/admin-x-design-system/src/assets/icons/linkedin.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="-0.75 -0.75 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M5.315625 21.215625H0.759375V8.15625h4.55625Zm9.459375 -8.803125000000001a2.00625 2.00625 0 0 0 -2.00625 2.00625v6.796875H7.9781249999999995V8.15625h4.790625v1.490625a6.3374999999999995 6.3374999999999995 0 0 1 4.0125 -1.5c2.971875 0 5.034375 2.203125 5.034375 6.3843749999999995v6.684375H16.78125v-6.796875a2.00625 2.00625 0 0 0 -2.00625 -2.015625Zm-9.375 -8.774999999999999a2.34375 2.34375 0 1 1 -2.34375 -2.34375 2.34375 2.34375 0 0 1 2.325 2.34375Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 667 B |
1
apps/admin-x-design-system/src/assets/icons/listview.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 24 24" height="24" width="24"><defs></defs><title>layout-headline</title><path d="M2.109375 0.7003125h18.28125s1.40625 0 1.40625 1.40625v1.40625s0 1.40625 -1.40625 1.40625H2.109375s-1.40625 0 -1.40625 -1.40625v-1.40625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M2.109375 9.137812499999999h18.28125s1.40625 0 1.40625 1.40625v1.40625s0 1.40625 -1.40625 1.40625H2.109375s-1.40625 0 -1.40625 -1.40625v-1.40625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M2.109375 17.5753125h18.28125s1.40625 0 1.40625 1.40625v1.40625s0 1.40625 -1.40625 1.40625H2.109375s-1.40625 0 -1.40625 -1.40625v-1.40625s0 -1.40625 1.40625 -1.40625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 995 B |
Before Width: | Height: | Size: 543 B After Width: | Height: | Size: 543 B |