diff --git a/.eslintrc.js b/.eslintrc.js index ec8762eb..14e14899 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,6 +16,8 @@ module.exports = { // See https://github.com/lightspeedretail/web-tools/issues/65 '@typescript-eslint/ban-types': 'error', 'jest/valid-describe': 'off', + // Allow css prop from Emotion v11 + 'react/no-unknown-property': ['error', { ignore: ['css'] }], }, overrides: [ { @@ -24,6 +26,12 @@ module.exports = { 'import/no-extraneous-dependencies': 'off', }, }, + { + files: ['**/*.test.tsx', '**/*.test.ts', '**/__tests__/*.tsx', '**/__tests__/*.ts'], + rules: { + 'import/no-extraneous-dependencies': 'off', + }, + }, ], settings: { // Using `export * ...` does not work with eslint-plugin-import and makes ESLint trips, diff --git a/.github/workflows/chromatic-label.yml b/.github/workflows/chromatic-label.yml index 735a415d..48d6ad24 100644 --- a/.github/workflows/chromatic-label.yml +++ b/.github/workflows/chromatic-label.yml @@ -6,6 +6,8 @@ jobs: name: Run visual regression tests with chromatic (label triggered) if: ${{ contains(github.event.pull_request.labels.*.name, 'snapshot') }} runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 with: @@ -16,8 +18,8 @@ jobs: - name: Setup node uses: actions/setup-node@v2 with: - node-version: '${{ steps.nvm.outputs.nvmrc }}' - - uses: actions/cache@v1 + node-version: "${{ steps.nvm.outputs.nvmrc }}" + - uses: actions/cache@v4 with: path: ~/.cache/yarn key: ${{ runner.OS }}-yarn-cache-v1-${{ hashFiles('**/yarn.lock') }} diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 8e437d2a..86b0ca53 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -10,6 +10,8 @@ jobs: snapshot: name: Run visual regression tests with chromatic runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 with: @@ -20,8 +22,8 @@ jobs: - name: Setup node uses: actions/setup-node@v1.1.1 with: - node-version: '${{ steps.nvm.outputs.nvmrc }}' - - uses: actions/cache@v1 + node-version: "${{ steps.nvm.outputs.nvmrc }}" + - uses: actions/cache@v4 with: path: ~/.cache/yarn key: ${{ runner.OS }}-yarn-cache-v1-${{ hashFiles('**/yarn.lock') }} diff --git a/.github/workflows/publish-lerna.yml b/.github/workflows/publish-lerna.yml index 809e860d..d39118c0 100644 --- a/.github/workflows/publish-lerna.yml +++ b/.github/workflows/publish-lerna.yml @@ -9,6 +9,8 @@ jobs: publish: name: Publish runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v1 - name: Dump GitHub context @@ -21,9 +23,9 @@ jobs: - name: Setup node uses: actions/setup-node@v2 with: - node-version: '${{ steps.nvm.outputs.nvmrc }}' - registry-url: https://registry.npmjs.org/ - - uses: actions/cache@v1 + node-version: "${{ steps.nvm.outputs.nvmrc }}" + registry-url: https://npm.pkg.github.com + - uses: actions/cache@v4 with: path: ~/.cache/yarn key: ${{ runner.OS }}-yarn-cache-v1-${{ hashFiles('**/yarn.lock') }} @@ -35,5 +37,3 @@ jobs: run: yarn bootstrap - name: Publish run: yarn lerna:publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} diff --git a/.github/workflows/publish-mainline.yml b/.github/workflows/publish-mainline.yml index 0ee7cce9..307600ed 100644 --- a/.github/workflows/publish-mainline.yml +++ b/.github/workflows/publish-mainline.yml @@ -9,6 +9,8 @@ jobs: publish: name: Publish runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v1 - name: Dump GitHub context @@ -21,9 +23,9 @@ jobs: - name: Setup node uses: actions/setup-node@v2 with: - node-version: '${{ steps.nvm.outputs.nvmrc }}' - registry-url: https://registry.npmjs.org/ - - uses: actions/cache@v1 + node-version: "${{ steps.nvm.outputs.nvmrc }}" + registry-url: https://npm.pkg.github.com + - uses: actions/cache@v4 with: path: ~/.cache/yarn key: ${{ runner.OS }}-yarn-cache-v1-${{ hashFiles('**/yarn.lock') }} @@ -36,6 +38,4 @@ jobs: - name: Publish run: | cd packages/flame - node ./scripts/check-changed.js && yarn build && yarn build:docgen && npm publish dist --quiet || exit 0 - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + node ./scripts/check-changed.js && yarn build && yarn build:docgen && npm publish ./dist --quiet || exit 0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fac40856..b08d0033 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,13 +3,15 @@ name: Test on: push: branches: - - '**' + - "**" tags-ignore: - - '**' + - "**" jobs: build: name: Test, lint, typecheck runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@master - name: Read .nvmrc @@ -18,8 +20,8 @@ jobs: - name: Setup node uses: actions/setup-node@v2 with: - node-version: '${{ steps.nvm.outputs.nvmrc }}' - - uses: actions/cache@v1 + node-version: "${{ steps.nvm.outputs.nvmrc }}" + - uses: actions/cache@v4 with: path: ~/.cache/yarn key: ${{ runner.OS }}-yarn-cache-v1-${{ hashFiles('**/yarn.lock') }} diff --git a/.gitignore b/.gitignore index 94840b4e..4737820c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ dist/ .DS_Store docgen-build .env +.yarn diff --git a/.npmrc b/.npmrc index 6f73a690..4589833c 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,4 @@ init-author-name=Lightspeed init-author-url=https://lightspeedhq.com -registry=https://registry.npmjs.org/ +@lightspeed:registry=https://npm.pkg.github.com +//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} diff --git a/.nvmrc b/.nvmrc index 5007551b..209e3ef4 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -10.16.0 +20 diff --git a/.storybook/addons/theme-switcher/register.js b/.storybook/addons/theme-switcher/register.js index c5e4dc27..21c42238 100644 --- a/.storybook/addons/theme-switcher/register.js +++ b/.storybook/addons/theme-switcher/register.js @@ -44,6 +44,18 @@ const ThemeSwitcher = () => { /> Lightspeed (Old theme) +
+ ); diff --git a/.storybook/main.js b/.storybook/main.js index 380ff767..990771f2 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -16,12 +16,17 @@ const babelOptions = { debug: false, }, ], - '@babel/preset-react', - '@emotion/babel-preset-css-prop', + [ + '@babel/preset-react', + { + runtime: 'automatic', + importSource: '@emotion/react', + }, + ], ], plugins: [ '@babel/plugin-proposal-object-rest-spread', - 'emotion', + '@emotion/babel-plugin', // need to resolve the dependency differently in storybook. // It's an issue on their side where they use an old version of // react-popper which magically clashes with ours diff --git a/.storybook/preview.js b/.storybook/preview.js index aca51c6c..71da24a3 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,5 +1,5 @@ import React from 'react'; -import { Global } from '@emotion/core'; +import { Global } from '@emotion/react'; import { addDecorator, addParameters } from '@storybook/react'; import { FlameGlobalStyles, FlameTheme, themePicker } from '../packages/flame/src/Core/index.tsx'; import './stories.scss'; diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 00000000..ca218b88 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,6 @@ +nodeLinker: node-modules + +npmScopes: + lightspeed: + npmAuthToken: '${GITHUB_TOKEN}' + npmRegistryServer: 'https://npm.pkg.github.com' diff --git a/README.md b/README.md index 50e28665..bb07ce02 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ If you have Emotion already installed and you would like to use the theme values ```jsx import React from 'react'; import { FlameTheme, lightTheme } from '@lightspeed/flame/Core'; -import { ThemeProvider } from 'emotion-theming'; +import { ThemeProvider } from '@emotion/react'; class App extends React.Component { render() { diff --git a/babel.config.js b/babel.config.js index b96d9297..9d641725 100644 --- a/babel.config.js +++ b/babel.config.js @@ -7,15 +7,26 @@ module.exports = { }, ], '@babel/preset-typescript', - '@babel/preset-react', - '@emotion/babel-preset-css-prop', + [ + '@babel/preset-react', + { + runtime: 'automatic', + importSource: '@emotion/react', + }, + ], ], - plugins: ['@babel/plugin-proposal-object-rest-spread'], + plugins: ['@babel/plugin-proposal-object-rest-spread', '@emotion/babel-plugin'], env: { test: { presets: [ '@babel/preset-typescript', - '@babel/preset-react', + [ + '@babel/preset-react', + { + runtime: 'automatic', + importSource: '@emotion/react', + }, + ], [ '@babel/preset-env', { @@ -26,17 +37,19 @@ module.exports = { }, }, ], - '@emotion/babel-preset-css-prop', ], + plugins: ['@emotion/babel-plugin'], }, // for ESM builds production: { - plugins: ['transform-react-remove-prop-types'], + plugins: ['transform-react-remove-prop-types', '@emotion/babel-plugin'], presets: [ + '@babel/preset-typescript', [ - '@emotion/babel-preset-css-prop', + '@babel/preset-react', { - sourceMap: false, + runtime: 'automatic', + importSource: '@emotion/react', }, ], [ @@ -45,23 +58,23 @@ module.exports = { modules: false, }, ], - '@babel/preset-typescript', ], }, cjs: { - plugins: ['transform-react-remove-prop-types'], + plugins: ['transform-react-remove-prop-types', '@emotion/babel-plugin'], presets: [ '@babel/preset-typescript', [ - '@babel/preset-env', + '@babel/preset-react', { - modules: 'commonjs', + runtime: 'automatic', + importSource: '@emotion/react', }, ], [ - '@emotion/babel-preset-css-prop', + '@babel/preset-env', { - sourceMap: false, + modules: 'commonjs', }, ], ], diff --git a/jest.setup.js b/jest.setup.js index 15fc7d82..931492d1 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -1,11 +1,9 @@ /* eslint-disable import/no-extraneous-dependencies */ import '@testing-library/jest-dom'; import { cleanup } from '@testing-library/react'; -import * as emotion from 'emotion'; -import { createSerializer, matchers as emotionMatchers } from 'jest-emotion'; +import { matchers } from '@emotion/jest'; -expect.addSnapshotSerializer(createSerializer(emotion)); -expect.extend(emotionMatchers); +expect.extend(matchers); afterEach(cleanup); diff --git a/lerna.json b/lerna.json index 9b26000d..806a6172 100644 --- a/lerna.json +++ b/lerna.json @@ -4,7 +4,7 @@ "version": "independent", "command": { "publish": { - "allowBranch": ["master", "next"], + "allowBranch": ["master", "next", "LSPAY-34879"], "ignoreChanges": [ "**/story.js", "**/story.tsx", @@ -18,7 +18,8 @@ "**/flame-sidebar/story/**", "**/packages/framerx/**", "packages/flame/scripts/check-changed.js" - ] + ], + "registry": "https://npm.pkg.github.com/" } }, "packages": ["packages/*"] diff --git a/package.json b/package.json index 0bbc784d..cdeec921 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "bugs": { "url": "https://github.com/lightspeed/flame/issues" }, + "packageManager": "yarn@1.22.22", "workspaces": [ "packages/*" ], @@ -19,7 +20,7 @@ "test:ci": "yarn test --coverage --runInBand && codecov", "typecheck": "tsc", "precommit": "lint-staged", - "dev": "yarn && concurrently --kill-others 'yarn dev:tokens' 'yarn dev:themes' 'yarn start-storybook -p 6006'", + "dev": "yarn && concurrently --kill-others 'yarn dev:tokens' 'yarn dev:themes' 'yarn start-storybook -p 6007'", "dev:themes": "chokidar './packages/flame/themes/**/*.ts' -c 'lerna run --scope @lightspeed/flame build:themes'", "dev:tokens": "chokidar './packages/flame-tokens/src/*.ts' -c 'lerna run --scope @lightspeed/flame-tokens prepublish'", "build-storybook": "yarn bootstrap && build-storybook -c .storybook", @@ -34,15 +35,15 @@ "percy": "build-storybook -c .storybook && percy-storybook --widths=1280" }, "dependencies": { - "@emotion/core": "^10.0.9", - "@emotion/styled": "^10.0.9", + "@emotion/cache": "^11.11.0", + "@emotion/react": "^11.11.0", + "@emotion/styled": "^11.11.0", "@styled-system/css": "^5.1.5", "@styled-system/theme-get": "5.0.16", - "emotion-theming": "^10.0.7", "polished": "^2.3.0", "prop-types": "^15.6.0", - "react": "^16.8.6", - "react-dom": "^16.8.6", + "react": "^18.3.1", + "react-dom": "^18.3.1", "styled-system": "^5.0.16" }, "devDependencies": { @@ -53,30 +54,31 @@ "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.1.0", "@babel/runtime": "^7.0.0", - "@emotion/babel-preset-css-prop": "^10.0.14", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/jest": "^11.11.0", "@lightspeed/browserslist-config": "^0.1.2", "@lightspeed/config-prettier": "^0.1.2", "@lightspeed/config-typescript": "^0.2.0", "@lightspeed/eslint-config": "^1.1.1", "@percy/storybook": "^3.3.0", - "@storybook/addon-actions": "6.1.15", - "@storybook/addon-docs": "6.1.15", - "@storybook/addons": "6.1.15", - "@storybook/api": "^6.1.15", - "@storybook/components": "6.1.15", - "@storybook/react": "6.1.15", + "@storybook/addon-actions": "6.5.16", + "@storybook/addon-docs": "6.5.16", + "@storybook/addons": "6.5.16", + "@storybook/api": "^6.5.16", + "@storybook/components": "6.5.16", + "@storybook/react": "6.5.16", "@testing-library/jest-dom": "^5.9.0", "@testing-library/react": "^10.0.5", "@types/classnames": "^2.2.7", "@types/jest": "^25.2.3", "@types/lodash": "^4.14.123", "@types/luxon": "^1.15.2", - "@types/react": "^16.8.23", + "@types/minimatch": "^3.0.3", + "@types/react": "^18.3.26", "@types/react-test-renderer": "^16.8.3", "babel-eslint": "^10.0.1", "babel-jest": "^26.0.1", "babel-loader": "^8.0.4", - "babel-plugin-emotion": "^10.0.0", "babel-plugin-module-resolver": "^4.0.0", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.13", @@ -95,7 +97,6 @@ "husky": "^0.14.3", "identity-obj-proxy": "^3.0.0", "jest": "^26.0.1", - "jest-emotion": "^10.0.0", "lerna": "^3.10.2", "lint-staged": "^7.1.2", "plop": "^2.4.0", @@ -103,20 +104,28 @@ "postcss-import": "^11.1.0", "postcss-loader": "^2.1.5", "prettier": "^1.16.1", - "react-test-renderer": "^16.8.6", "raw-loader": "4.0.1", + "react-docgen-typescript": "~2.2.2", + "react-test-renderer": "^18.3.1", "sass": "^1.14.3", "sass-loader": "^7.1.0", - "storybook-readme": "^5.0.8", "style-loader": "^0.21.0", - "typescript": "^3.5.3", + "typescript": "^4.9.5", "webpack": "^4.41.2", "webpack-cli": "^2.1.3", "yargs": "^11.0.0" }, "resolutions": { - "@types/react": "16.8.23", - "react-docgen-typescript": "1.18.0" + "@types/react": "18.3.26", + "@types/react-dom": "^18.0.0", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-docgen-typescript": "~2.2.2", + "@emotion/react": "^11.11.0", + "@emotion/core": "npm:@emotion/react@^11.11.0", + "@emotion/styled": "^11.11.0", + "@emotion/styled-base": "npm:@emotion/styled@^11.11.0", + "emotion-theming": "npm:@emotion/react@^11.11.0" }, "lint-staged": { "*.{ts,tsx,js,jsx,json,css,scss,md}": [ diff --git a/packages/flame-tokens/CHANGELOG.md b/packages/flame-tokens/CHANGELOG.md index ae690e23..93860657 100644 --- a/packages/flame-tokens/CHANGELOG.md +++ b/packages/flame-tokens/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Refer to the [CONTRIBUTING guide](https://github.com/lightspeed/flame/blob/master/.github/CONTRIBUTING.md) for more info. +## 2.0.0-helios.1 - 2025-11-24 + +- Version bump because lerna + +## 2.0.0-alpha.10 - 2025-10-29 + +- Version bump because lerna + +## 2.0.0-alpha.1 - 2025-10-26 + +- Version bump because lerna + +## 2.0.0-alpha.0 - 2025-10-26 + +- Version bump because lerna + ## 1.0.1 - 2021-01-28 - Version bump because lerna diff --git a/packages/flame-tokens/package.json b/packages/flame-tokens/package.json index 337e8f70..2aa0553d 100644 --- a/packages/flame-tokens/package.json +++ b/packages/flame-tokens/package.json @@ -1,6 +1,6 @@ { "name": "@lightspeed/flame-tokens", - "version": "1.0.1", + "version": "2.0.0-helios.1", "description": "Design tokens for Lightspeed's Flame design system", "main": "dist/index.js", "module": "dist/esm/index.js", @@ -32,6 +32,8 @@ "prepublish": "yarn clean && yarn build && node ../../scripts/validate-build" }, "publishConfig": { + "registry": "https://npm.pkg.github.com", "access": "public" - } + }, + "gitHead": "e43393afac001fcabc4ca191609404daff1382ba" } diff --git a/packages/flame-tokens/src/__tests__/typography.test.js b/packages/flame-tokens/src/__tests__/typography.test.js index 70e51b60..4bffbd9f 100644 --- a/packages/flame-tokens/src/__tests__/typography.test.js +++ b/packages/flame-tokens/src/__tests__/typography.test.js @@ -1,4 +1,4 @@ -const { fontSizes, fontSizeAliases } = require('../typography'); +const { fontSizes, fontSizeAliases } = require('../typography.ts'); describe('fontSizes', () => { it('returns list of rem value by size', () => { diff --git a/packages/flame-tokens/src/__tests__/utils.test.js b/packages/flame-tokens/src/__tests__/utils.test.js index 8459fadc..6f235958 100644 --- a/packages/flame-tokens/src/__tests__/utils.test.js +++ b/packages/flame-tokens/src/__tests__/utils.test.js @@ -1,4 +1,4 @@ -const { pxToRem } = require('../utils'); +const { pxToRem } = require('../utils.ts'); describe('pxToRem', () => { it('returns rem value with default base value', () => { diff --git a/packages/flame-tokens/tsconfig.types.json b/packages/flame-tokens/tsconfig.types.json index 56a0ae8c..70634098 100644 --- a/packages/flame-tokens/tsconfig.types.json +++ b/packages/flame-tokens/tsconfig.types.json @@ -6,7 +6,9 @@ "noEmit": false, "declaration": true, "emitDeclarationOnly": true, - "lib": ["es2017", "dom"] + "lib": ["es2017", "dom"], + "skipLibCheck": true, + "types": ["node"] }, "include": ["./typings", "./src/**/*.ts", "./src/**/*.tsx"], "exclude": ["**/*.test.ts", "**/*.test.tsx", "**/story.tsx"] diff --git a/packages/flame/CHANGELOG.md b/packages/flame/CHANGELOG.md index 341481c4..f536d435 100644 --- a/packages/flame/CHANGELOG.md +++ b/packages/flame/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Refer to the [CONTRIBUTING guide](https://github.com/lightspeed/flame/blob/master/.github/CONTRIBUTING.md) for more info. +## 3.0.0-helios.1 - 2025-11-24 + +- Version bump because lerna + +## 3.0.0-alpha.10 - 2025-10-29 + +- Version bump because lerna + +## 3.0.0-alpha.1 - 2025-10-26 + +- Version bump because lerna + +## 3.0.0-alpha.0 - 2025-10-26 + +- Version bump because lerna + ## 2.4.5 - 2022-11-16 ### Dependencies diff --git a/packages/flame/package.json b/packages/flame/package.json index dd707eec..c9b13680 100644 --- a/packages/flame/package.json +++ b/packages/flame/package.json @@ -1,6 +1,6 @@ { "name": "@lightspeed/flame", - "version": "2.4.5", + "version": "3.0.0-helios.1", "private": true, "description": "Lightspeed's React UI components library", "author": "Lightspeed", @@ -27,18 +27,18 @@ "build:docgen": "node ./scripts/docgen.js", "build:private-to-public": "node ./scripts/private-to-public.js", "build": "yarn build:icons && yarn build:flags && yarn build:themes && yarn build:cjs && yarn build:esm && yarn build:copy-files && yarn build:types && yarn build:types:esm && yarn build:private-to-public && node ../../scripts/validate-build", - "release": "yarn build && yarn build:docgen && npm publish dist --quiet", - "release:dryrun": "npm publish dist --dry-run" + "release": "yarn build && yarn build:docgen && npm publish ./dist --quiet", + "release:dryrun": "npm publish ./dist --dry-run" }, "peerDependencies": { - "@emotion/core": "^10.0.0", - "@emotion/styled": "^10.0.0", - "emotion-theming": "^10.0.0", - "react": "^16.8.0-0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "react": "^16.8.0-0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "dependencies": { - "@popperjs/core": "^2.4.2", + "@lightspeed/unified-tokens": "^3.3.0", + "@popperjs/core": "^2.11.8", "@styled-system/css": "^5.1.5", "@styled-system/theme-get": "5.0.16", "@types/react-toast-notifications": "^2.4.0", @@ -52,7 +52,7 @@ "type-fest": "^0.3.0" }, "devDependencies": { - "@lightspeed/flame-tokens": "^1.0.1", + "@lightspeed/flame-tokens": "^2.0.0-helios.1", "@types/lodash": "^4.14.123", "@types/react-modal": "^3.8.1", "@types/react-select": "^2.0.15", @@ -60,13 +60,13 @@ "@types/styled-system__theme-get": "^5.0.0", "fs-extra": "7.0.1", "glob": "7.1.3", - "htmltojsx": "^0.3.0", "lodash": "^4.17.11", "rimraf": "2.6.2", "svgo": "^1.3.2", "ts-node": "8.3.0" }, "publishConfig": { + "registry": "https://npm.pkg.github.com", "tag": "next" } } diff --git a/packages/flame/scripts/build-themes.ts b/packages/flame/scripts/build-themes.ts index b1473358..f3d327a3 100644 --- a/packages/flame/scripts/build-themes.ts +++ b/packages/flame/scripts/build-themes.ts @@ -1,6 +1,7 @@ import { theme as flameTheme, themeUI as flameThemeUI } from '../themes/flame'; import { theme as oldSkoolTheme } from '../themes/oldskool'; import { theme as darkTheme } from '../themes/dark'; +import { theme as heliosTheme } from '../themes/helios'; // @ts-ignore const fs = require('fs'); @@ -97,6 +98,10 @@ const themeList: ThemeList = [ filename: 'dark', themeObject: darkTheme, }, + { + filename: 'helios', + themeObject: heliosTheme, + }, ]; // @ts-ignore diff --git a/packages/flame/scripts/generate-flags.js b/packages/flame/scripts/generate-flags.js index 1be00d4c..586105ec 100644 --- a/packages/flame/scripts/generate-flags.js +++ b/packages/flame/scripts/generate-flags.js @@ -1,7 +1,6 @@ const fs = require('fs-extra'); const path = require('path'); const prettier = require('prettier'); -const HTMLtoJSX = require('htmltojsx'); const _ = require('lodash'); const prettierConfig = require('../../../prettier.config'); @@ -10,15 +9,61 @@ delete prettierConfig.overrides; // TODO: use prettier.resolveConfigFile instead... prettierConfig.parser = 'babel'; +// Function to sanitize SVG attributes for JSX compatibility +const sanitizeSvgForJsx = svg => { + return ( + svg + // Remove xmlns:xlink attribute (not needed in JSX) + .replace(/\s*xmlns:xlink="[^"]*"/g, '') + // Convert class to className + .replace(/\sclass=/g, ' className=') + // Convert all kebab-case and colon-separated attributes to camelCase + // e.g., stroke-width -> strokeWidth, xlink:href -> xlinkHref + .replace(/\b([a-z]+)([-:][a-z-:]+)=/g, (match, p1, p2) => { + const camelCase = p1 + p2.replace(/[-:]([a-z])/g, (_0, letter) => letter.toUpperCase()); + return `${camelCase}=`; + }) + // Convert non-string primitives to JSX expressions + // Only integers and booleans, keep decimals as strings + // e.g., width="16" -> width={16}, r="3.5" -> r="3.5" + .replace(/\b([a-zA-Z][a-zA-Z0-9]*)="([^"]*)"/g, (match, attr, value) => { + // Check if it's an integer (not a decimal) + if (/^-?\d+$/.test(value)) { + return `${attr}={${value}}`; + } + // Check if it's a boolean or null + if (value === 'true' || value === 'false' || value === 'null') { + return `${attr}={${value}}`; + } + // Otherwise (including decimals), keep as string + return match; + }) + // Convert style attributes to JSX style objects + .replace(/style="([^"]*)"/g, (match, styleContent) => { + // Parse CSS properties and convert to camelCase object notation + const styles = styleContent + .split(';') + .filter(s => s.trim()) + .map(prop => { + const [key, value] = prop.split(':').map(s => s.trim()); + if (!key || !value) return ''; + // Convert kebab-case to camelCase + const camelKey = key.replace(/-([a-z])/g, (_0, letter) => letter.toUpperCase()); + return `${camelKey}: '${value}'`; + }) + .filter(s => s) + .join(', '); + return styles ? `style={{ ${styles} }}` : ''; + }) + ); +}; + const svgDirPath = `./svg/Flags/`; const sourceDirPath = './src/Flag'; const flagsDirPath = `${sourceDirPath}`; const componentFlagISOs = []; const spriteSvg = []; -// Used to replace SVG html attributes into JSX, ex: xlink:href -> xlinkHref -const converter = new HTMLtoJSX({ createClass: false }); - if (!fs.existsSync(flagsDirPath)) { fs.mkdirSync(flagsDirPath); } @@ -40,12 +85,11 @@ fs.readdir(svgDirPath, (err, svgPaths) => { const flagISO = svgPath.replace(/.+?([^/]+)\.svg/i, '$1').replace(/\s|\(.+?\)/g, ''); const componentFlagISO = flagISO.replace('-', '_'); - const componentSvg = converter - .convert(svg) - .replace( - //, - '', - ); + // Sanitize SVG attributes and replace the opening svg tag + const componentSvg = sanitizeSvgForJsx(svg).replace( + /]*>/i, + '', + ); const component = ` import * as React from 'react'; diff --git a/packages/flame/src/Autocomplete/Autocomplete.test.tsx b/packages/flame/src/Autocomplete/Autocomplete.test.tsx index ff32b890..64352f3d 100644 --- a/packages/flame/src/Autocomplete/Autocomplete.test.tsx +++ b/packages/flame/src/Autocomplete/Autocomplete.test.tsx @@ -112,7 +112,7 @@ describe('Autocomplete', () => { ); const input = container.querySelector('input#color-input'); fireEvent.change(input, { target: { value: 'new option' } }); - fireEvent.click(getByText('Add “new option”')); + fireEvent.click(getByText('Add "new option"')); }); }); }); diff --git a/packages/flame/src/Autocomplete/Autocomplete.tsx b/packages/flame/src/Autocomplete/Autocomplete.tsx index f43ca250..40f0f153 100644 --- a/packages/flame/src/Autocomplete/Autocomplete.tsx +++ b/packages/flame/src/Autocomplete/Autocomplete.tsx @@ -11,7 +11,7 @@ import { Props as BaseSelectProps } from 'react-select/lib/Select'; import { Props as BaseCreatableProps } from 'react-select/lib/Creatable'; import { Props as BaseAsyncProps } from 'react-select/lib/Async'; -import { withTheme } from 'emotion-theming'; +import { withTheme } from '@emotion/react'; import { Spinner } from '../Spinner'; import { IconSmallChevronDown } from '../Icon/SmallChevronDown'; diff --git a/packages/flame/src/Autocomplete/__snapshots__/Autocomplete.test.tsx.snap b/packages/flame/src/Autocomplete/__snapshots__/Autocomplete.test.tsx.snap index 18861deb..9662de43 100644 --- a/packages/flame/src/Autocomplete/__snapshots__/Autocomplete.test.tsx.snap +++ b/packages/flame/src/Autocomplete/__snapshots__/Autocomplete.test.tsx.snap @@ -1,154 +1,25 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Autocomplete renders as disabled 1`] = ` -.emotion-7 { - position: relative; - box-sizing: border-box; -} - -.emotion-6 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #fff; - border-color: #abb3b3; - border-radius: 0.1875rem; - border-style: solid; - border-width: 1px; - box-shadow: inset 0 0.0625rem 0.125rem rgba(56,61,61,0.1); - cursor: default; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - min-height: 2.25rem; - outline: 0 !important; - position: relative; - -webkit-transition: all 100ms; - transition: all 100ms; - box-sizing: border-box; - font-family: Lato,Helvetica Neue,Helvetica,Arial,sans-serif; - font-size: 0.875rem; - color: #494c4c; -} - -.emotion-6:hover { - border-color: hsl(0,0%,70%); -} - -.emotion-6:hover { - border-color: #848a8a; -} - -.cr-autocomplete--error .emotion-6 { - border-color: #b93435; -} - -.cr-autocomplete--error .emotion-6 .cr-autocomplete__dropdownIndicator { - fill: #b93435; -} - -.emotion-2 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - padding: 2px 8px; - -webkit-overflow-scrolling: touch; - position: relative; - overflow: hidden; - box-sizing: border-box; -} - -.emotion-0 { - color: #abb3b3; - margin-left: 2px; - margin-right: 2px; - position: absolute; - top: 50%; - -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); - transform: translateY(-50%); - box-sizing: border-box; -} - -.emotion-1 { - margin: 2px; - padding-bottom: 2px; - padding-top: 2px; - visibility: visible; - color: hsl(0,0%,20%); - box-sizing: border-box; -} - -.emotion-5 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-self: stretch; - -ms-flex-item-align: stretch; - align-self: stretch; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - box-sizing: border-box; - opacity: 1; - cursor: pointer; - color: #848a8a; -} - -.emotion-5 div:hover .cr-autocomplete__clearIndicator { - fill: #b93435; -} - -.emotion-3 { - width: 1rem; - height: 1rem; - vertical-align: text-bottom; -} -
Choose a color
- -
+ />