feat: Wrapped up work on measurements sets
This commit is contained in:
parent
770b608090
commit
dbe1a04552
23 changed files with 1292 additions and 359 deletions
205
CHANGELOG.md
205
CHANGELOG.md
|
@ -1086,6 +1086,16 @@
|
||||||
- Migrated from Rollup to Esbuild for all builds
|
- Migrated from Rollup to Esbuild for all builds
|
||||||
- The `pctBasedOn()` helper method for pattern config was moved to config-helpers We did not make this a breaking change since it's only used internally.
|
- The `pctBasedOn()` helper method for pattern config was moved to config-helpers We did not make this a breaking change since it's only used internally.
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Migrated from Rollup to Esbuild for all builds
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Added missing lab namespace for English
|
||||||
|
|
||||||
### models
|
### models
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
@ -1225,6 +1235,12 @@
|
||||||
|
|
||||||
## 2.20.2 (2022-01-27)
|
## 2.20.2 (2022-01-27)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Patterns options were always in English due to symlinks being used
|
||||||
|
|
||||||
|
|
||||||
## 2.20.1 (2022-01-27)
|
## 2.20.1 (2022-01-27)
|
||||||
|
|
||||||
|
@ -1553,6 +1569,12 @@
|
||||||
|
|
||||||
- Added support for `settings.scale`
|
- Added support for `settings.scale`
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fixed issue that was causing plugin translations to always be in English
|
||||||
|
|
||||||
|
|
||||||
## 2.19.9 (2022-01-09)
|
## 2.19.9 (2022-01-09)
|
||||||
|
|
||||||
|
@ -1985,6 +2007,13 @@
|
||||||
|
|
||||||
- Pattern.on() is now chainable as it returns the Pattern object
|
- Pattern.on() is now chainable as it returns the Pattern object
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fixed bug in resolving of shared pattern options
|
||||||
|
- Removed optional chaining which broke node v12 support
|
||||||
|
|
||||||
### snapseries
|
### snapseries
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
@ -2031,6 +2060,16 @@
|
||||||
|
|
||||||
- Handle path.offset() of very short curves with control points on the start or end point Closes [#1257](https://github.com/freesewing/freesewing/issues/1257)
|
- Handle path.offset() of very short curves with control points on the start or end point Closes [#1257](https://github.com/freesewing/freesewing/issues/1257)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added translations for Yuri
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Added optional chaining so missing options always lead to clear error message
|
||||||
|
|
||||||
|
|
||||||
## 2.17.4 (2021-08-20)
|
## 2.17.4 (2021-08-20)
|
||||||
|
|
||||||
|
@ -2043,6 +2082,12 @@
|
||||||
|
|
||||||
## 2.17.3 (2021-08-16)
|
## 2.17.3 (2021-08-16)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- New translations
|
||||||
|
|
||||||
### utils
|
### utils
|
||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
|
@ -2064,6 +2109,12 @@
|
||||||
|
|
||||||
- Added new ffsa option to let the user control the extra SA for flat-felled seams Closes [#1251](https://github.com/freesewing/freesewing/issues/1251)
|
- Added new ffsa option to let the user control the extra SA for flat-felled seams Closes [#1251](https://github.com/freesewing/freesewing/issues/1251)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added new ffsa option for simon & simone
|
||||||
|
|
||||||
### models
|
### models
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
@ -2185,9 +2236,21 @@
|
||||||
|
|
||||||
- Fix a bug in `path.shiftAlong` where no point is returned if the distance to shift is a fraction of one step (1/25mm) into a new path segment See [#1140](https://github.com/freesewing/freesewing/issues/1140)
|
- Fix a bug in `path.shiftAlong` where no point is returned if the distance to shift is a fraction of one step (1/25mm) into a new path segment See [#1140](https://github.com/freesewing/freesewing/issues/1140)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Changed antman references to antperson
|
||||||
|
|
||||||
|
|
||||||
## 2.16.2 (2021-05-05)
|
## 2.16.2 (2021-05-05)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- String updates
|
||||||
|
|
||||||
|
|
||||||
## 2.16.1 (2021-05-30)
|
## 2.16.1 (2021-05-30)
|
||||||
|
|
||||||
|
@ -2395,6 +2458,12 @@
|
||||||
|
|
||||||
- Changed `department` setting in config in line with new grouping
|
- Changed `department` setting in config in line with new grouping
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- New translations for pattern filter
|
||||||
|
|
||||||
### utils
|
### utils
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
@ -2430,6 +2499,12 @@
|
||||||
|
|
||||||
- Fixed third button not showing up See [#973](https://github.com/freesewing/freesewing/issues/973)
|
- Fixed third button not showing up See [#973](https://github.com/freesewing/freesewing/issues/973)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Changes to cfp strings
|
||||||
|
|
||||||
|
|
||||||
## 2.15.4 (2021-05-08)
|
## 2.15.4 (2021-05-08)
|
||||||
|
|
||||||
|
@ -2561,6 +2636,13 @@
|
||||||
|
|
||||||
- Don't round coordinates internally to avoid path.split misses
|
- Don't round coordinates internally to avoid path.split misses
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added translation for new Titan options
|
||||||
|
- Added translations for Charlie
|
||||||
|
|
||||||
|
|
||||||
## 2.14.0 (2021-03-07)
|
## 2.14.0 (2021-03-07)
|
||||||
|
|
||||||
|
@ -2576,6 +2658,12 @@
|
||||||
|
|
||||||
- Replaced grainline indicator on pocket with cut-on-fold indicator
|
- Replaced grainline indicator on pocket with cut-on-fold indicator
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added translations for Cornelius
|
||||||
|
|
||||||
|
|
||||||
## 2.13.2 (2021-02-21)
|
## 2.13.2 (2021-02-21)
|
||||||
|
|
||||||
|
@ -2683,6 +2771,12 @@
|
||||||
|
|
||||||
- Make sure roudEnd and roundStart points are always available
|
- Make sure roudEnd and roundStart points are always available
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Translation for Hortensia
|
||||||
|
|
||||||
|
|
||||||
## 2.12.1 (2021-01-27)
|
## 2.12.1 (2021-01-27)
|
||||||
|
|
||||||
|
@ -2807,6 +2901,16 @@
|
||||||
|
|
||||||
- Removed unused lengthBonus option
|
- Removed unused lengthBonus option
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- New strings for new features
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Type in Simon title
|
||||||
|
|
||||||
|
|
||||||
## 2.10.7 (2020-11-18)
|
## 2.10.7 (2020-11-18)
|
||||||
|
|
||||||
|
@ -2822,6 +2926,12 @@
|
||||||
|
|
||||||
## 2.10.5 (2020-11-14)
|
## 2.10.5 (2020-11-14)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Added missing `cty.` translations to non-English language files
|
||||||
|
|
||||||
|
|
||||||
## 2.10.4 (2020-11-13)
|
## 2.10.4 (2020-11-13)
|
||||||
|
|
||||||
|
@ -2884,6 +2994,18 @@
|
||||||
- Added the `info` type to raised events
|
- Added the `info` type to raised events
|
||||||
- Added support for conditional loading of plugins
|
- Added support for conditional loading of plugins
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added translations for plugin-title
|
||||||
|
- Added translations for teagan
|
||||||
|
- Added some translations for the UI
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Replaced a few identical files with symlinks
|
||||||
|
|
||||||
|
|
||||||
## 2.8.1 (2020-08-16)
|
## 2.8.1 (2020-08-16)
|
||||||
|
|
||||||
|
@ -3277,6 +3399,13 @@
|
||||||
|
|
||||||
- [Properly escape quotes in imperial units](https://github.com/freesewing/freesewing/issues/437)
|
- [Properly escape quotes in imperial units](https://github.com/freesewing/freesewing/issues/437)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Added translations for Titan
|
||||||
|
- Removed `Circumference` suffix from measurement names
|
||||||
|
|
||||||
### models
|
### models
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
@ -3344,6 +3473,12 @@
|
||||||
- utils now includes `Bezier` which holds the bezier-js library so you don't need to re-import it
|
- utils now includes `Bezier` which holds the bezier-js library so you don't need to re-import it
|
||||||
- We no longer set the plugin configuration/data object to fall in `pattern.use()`
|
- We no longer set the plugin configuration/data object to fall in `pattern.use()`
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Changes to support the renaming of @freesewing/fu to @freesewing/florence
|
||||||
|
|
||||||
|
|
||||||
## 2.5.0 (2020-04-05)
|
## 2.5.0 (2020-04-05)
|
||||||
|
|
||||||
|
@ -3353,9 +3488,21 @@
|
||||||
|
|
||||||
- Diana is a top with a draped neck
|
- Diana is a top with a draped neck
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- title, description, and options for Dianna
|
||||||
|
|
||||||
|
|
||||||
## 2.4.6 (2020-03-23)
|
## 2.4.6 (2020-03-23)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fixed an bug in the i18n package
|
||||||
|
|
||||||
|
|
||||||
## 2.4.5 (2020-03-19)
|
## 2.4.5 (2020-03-19)
|
||||||
|
|
||||||
|
@ -3413,9 +3560,21 @@
|
||||||
|
|
||||||
## 2.4.3 (2020-03-12)
|
## 2.4.3 (2020-03-12)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added more translations
|
||||||
|
|
||||||
|
|
||||||
## 2.4.2 (2020-03-08)
|
## 2.4.2 (2020-03-08)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added more strings
|
||||||
|
|
||||||
|
|
||||||
## 2.4.1 (2020-03-04)
|
## 2.4.1 (2020-03-04)
|
||||||
|
|
||||||
|
@ -3588,6 +3747,22 @@
|
||||||
- Added the `Path.noop()` method
|
- Added the `Path.noop()` method
|
||||||
- Added the `Path.insop()` methods
|
- Added the `Path.insop()` methods
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added translations for Breanna
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Added/Updated strings for the 2.2 frontend changes
|
||||||
|
- Changed `Joost De Cock` to `Joost` because spam filters don't like cock
|
||||||
|
|
||||||
|
#### Removed
|
||||||
|
|
||||||
|
- Removed the files for homepage translation, and moved that content to markdown
|
||||||
|
- Removed the files for editor translation, as it is no longer used
|
||||||
|
|
||||||
### models
|
### models
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
@ -3652,6 +3827,12 @@
|
||||||
|
|
||||||
## 2.1.3 (2019-10-18)
|
## 2.1.3 (2019-10-18)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- More translated strings
|
||||||
|
|
||||||
### utils
|
### utils
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
@ -3665,6 +3846,12 @@
|
||||||
|
|
||||||
## 2.1.2 (2019-10-14)
|
## 2.1.2 (2019-10-14)
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fixed issue where symlinks were causing all languages to export English strings
|
||||||
|
|
||||||
|
|
||||||
## 2.1.1 (2019-10-13)
|
## 2.1.1 (2019-10-13)
|
||||||
|
|
||||||
|
@ -3719,6 +3906,12 @@
|
||||||
|
|
||||||
- The pattern super constructor now sets a `config` property that holds the pattern configuration. This means that unlike before, there is no need to instantiate a pattern to access its config. You can just import the pattern, and it's config property will contain the pattern config.
|
- The pattern super constructor now sets a `config` property that holds the pattern configuration. This means that unlike before, there is no need to instantiate a pattern to access its config. You can just import the pattern, and it's config property will contain the pattern config.
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Added translations for Penelope, Waralee, and Simone
|
||||||
|
|
||||||
### utils
|
### utils
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
@ -3777,6 +3970,12 @@
|
||||||
- [#102](https://github.com/freesewing/freesewing.org/issues/102): Fixed 'Snippets not defined' error when drafting a seperate button placket
|
- [#102](https://github.com/freesewing/freesewing.org/issues/102): Fixed 'Snippets not defined' error when drafting a seperate button placket
|
||||||
- [#103](https://github.com/freesewing/freesewing.org/issues/103): Fixed 'hemSa not defined' when drafting paperless Simon without seam allowance
|
- [#103](https://github.com/freesewing/freesewing.org/issues/103): Fixed 'hemSa not defined' when drafting paperless Simon without seam allowance
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- [#90](https://github.com/freesewing/freesewing/issues/90): Added missing option translations for Benjamin, Florent, Sandy, Shin, and Theo
|
||||||
|
|
||||||
### utils
|
### utils
|
||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
|
@ -3980,6 +4179,12 @@
|
||||||
|
|
||||||
### core
|
### core
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Initial release
|
||||||
|
|
||||||
|
### i18n
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
|
||||||
- Initial release
|
- Initial release
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"collection": "All FreeSewing designs bundles into one pacakge, our collection",
|
"collection": "All FreeSewing designs bundles into one pacakge, our collection",
|
||||||
"config": "Various configurations for FreeSewing",
|
"config": "Various configurations for FreeSewing",
|
||||||
"core": "A library for creating made-to-measure sewing patterns",
|
"core": "A library for creating made-to-measure sewing patterns",
|
||||||
|
"i18n": "Translation for the FreeSewing project",
|
||||||
"models": "Body measurements data for a range of default sizes",
|
"models": "Body measurements data for a range of default sizes",
|
||||||
"new-design": "Initializer package for a new FreeSewing design: npx @freesewing/new-design",
|
"new-design": "Initializer package for a new FreeSewing design: npx @freesewing/new-design",
|
||||||
"prettier-config": "FreeSewing's shared configuration for prettier",
|
"prettier-config": "FreeSewing's shared configuration for prettier",
|
||||||
|
|
|
@ -119,3 +119,16 @@ export const designs = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const collection = Object.keys(designs)
|
export const collection = Object.keys(designs)
|
||||||
|
|
||||||
|
export const requiredMeasurements = {}
|
||||||
|
export const optionalMeasurements = {}
|
||||||
|
export const measurements = {}
|
||||||
|
|
||||||
|
for (const design in designs) {
|
||||||
|
requiredMeasurements[design] = designs[design].patternConfig.measurements
|
||||||
|
optionalMeasurements[design] = designs[design].patternConfig.optionalMeasurements
|
||||||
|
measurements[design] = [
|
||||||
|
...designs[design].patternConfig.measurements,
|
||||||
|
...designs[design].patternConfig.optionalMeasurements,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
222
packages/i18n/CHANGELOG.md
Normal file
222
packages/i18n/CHANGELOG.md
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
# Change log for: @freesewing/i18n
|
||||||
|
|
||||||
|
|
||||||
|
## 3.0.0 (2023-09-30)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- All FreeSewing packages are now ESM only.
|
||||||
|
- All FreeSewing packages now use named exports.
|
||||||
|
- Dropped support for NodeJS 14. NodeJS 18 (LTS/hydrogen) or more recent is now required.
|
||||||
|
|
||||||
|
## 2.21.0 (2022-06-27)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Migrated from Rollup to Esbuild for all builds
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Added missing lab namespace for English
|
||||||
|
|
||||||
|
## 2.20.2 (2022-01-27)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Patterns options were always in English due to symlinks being used
|
||||||
|
|
||||||
|
## 2.20.0 (2022-01-24)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed issue that was causing plugin translations to always be in English
|
||||||
|
|
||||||
|
## 2.19.0 (2021-10-17)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed bug in resolving of shared pattern options
|
||||||
|
- Removed optional chaining which broke node v12 support
|
||||||
|
|
||||||
|
## 2.18.0 (2021-09-09)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added translations for Yuri
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Added optional chaining so missing options always lead to clear error message
|
||||||
|
|
||||||
|
## 2.17.3 (2021-08-16)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New translations
|
||||||
|
|
||||||
|
## 2.17.2 (2021-08-15)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added new ffsa option for simon & simone
|
||||||
|
|
||||||
|
## 2.17.0 (2021-07-01)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Changed antman references to antperson
|
||||||
|
|
||||||
|
## 2.16.2 (2021-05-05)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- String updates
|
||||||
|
|
||||||
|
## 2.16.1 (2021-05-30)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New translations for pattern filter
|
||||||
|
|
||||||
|
## 2.16.0 (2021-05-24)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Changes to cfp strings
|
||||||
|
|
||||||
|
## 2.15.0 (2021-04-15)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added translation for new Titan options
|
||||||
|
- Added translations for Charlie
|
||||||
|
|
||||||
|
## 2.14.0 (2021-03-07)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added translations for Cornelius
|
||||||
|
|
||||||
|
## 2.13.0 (2021-02-13)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Translation for Hortensia
|
||||||
|
|
||||||
|
## 2.11.0 (2021-01-10)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- New strings for new features
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Type in Simon title
|
||||||
|
|
||||||
|
## 2.10.5 (2020-11-14)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Added missing `cty.` translations to non-English language files
|
||||||
|
|
||||||
|
## 2.9.0 (2020-10-02)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added translations for plugin-title
|
||||||
|
- Added translations for teagan
|
||||||
|
- Added some translations for the UI
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Replaced a few identical files with symlinks
|
||||||
|
|
||||||
|
## 2.7.0 (2020-07-12)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Added translations for Titan
|
||||||
|
- Removed `Circumference` suffix from measurement names
|
||||||
|
|
||||||
|
## 2.6.0 (2020-05-01)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Changes to support the renaming of @freesewing/fu to @freesewing/florence
|
||||||
|
|
||||||
|
## 2.5.0 (2020-04-05)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- title, description, and options for Dianna
|
||||||
|
|
||||||
|
## 2.4.6 (2020-03-23)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed an bug in the i18n package
|
||||||
|
|
||||||
|
## 2.4.3 (2020-03-12)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added more translations
|
||||||
|
|
||||||
|
## 2.4.2 (2020-03-08)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added more strings
|
||||||
|
|
||||||
|
## 2.2.0 (2020-02-22)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added translations for Breanna
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Added/Updated strings for the 2.2 frontend changes
|
||||||
|
- Changed `Joost De Cock` to `Joost` because spam filters don't like cock
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Removed the files for homepage translation, and moved that content to markdown
|
||||||
|
- Removed the files for editor translation, as it is no longer used
|
||||||
|
|
||||||
|
## 2.1.3 (2019-10-18)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- More translated strings
|
||||||
|
|
||||||
|
## 2.1.2 (2019-10-14)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed issue where symlinks were causing all languages to export English strings
|
||||||
|
|
||||||
|
## 2.1.0 (2019-10-06)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added translations for Penelope, Waralee, and Simone
|
||||||
|
|
||||||
|
## 2.0.2 (2019-09-06)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- [#90](https://github.com/freesewing/freesewing/issues/90): Added missing option translations for Benjamin, Florent, Sandy, Shin, and Theo
|
||||||
|
|
||||||
|
## 2.0.0 (2019-08-25)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Initial release
|
||||||
|
|
||||||
|
|
||||||
|
This is the **initial release**, and the start of this change log.
|
||||||
|
|
||||||
|
> Prior to version 2, FreeSewing was not a JavaScript project.
|
||||||
|
> As such, that history is out of scope for this change log.
|
||||||
|
|
162
packages/i18n/README.md
Normal file
162
packages/i18n/README.md
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
<p align='center'><a
|
||||||
|
href="https://www.npmjs.com/package/@freesewing/i18n"
|
||||||
|
title="@freesewing/i18n on NPM"
|
||||||
|
><img src="https://img.shields.io/npm/v/@freesewing/i18n.svg"
|
||||||
|
alt="@freesewing/i18n on NPM"/>
|
||||||
|
</a><a
|
||||||
|
href="https://opensource.org/licenses/MIT"
|
||||||
|
title="License: MIT"
|
||||||
|
><img src="https://img.shields.io/npm/l/@freesewing/i18n.svg?label=License"
|
||||||
|
alt="License: MIT"/>
|
||||||
|
</a><a
|
||||||
|
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
|
||||||
|
title="Code quality on DeepScan"
|
||||||
|
><img src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
|
||||||
|
alt="Code quality on DeepScan"/>
|
||||||
|
</a><a
|
||||||
|
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen+label%3Apkg%3Ai18n"
|
||||||
|
title="Open issues tagged pkg:i18n"
|
||||||
|
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:i18n.svg?label=Issues"
|
||||||
|
alt="Open issues tagged pkg:i18n"/>
|
||||||
|
</a><a
|
||||||
|
href="#contributors-"
|
||||||
|
title="All Contributors"
|
||||||
|
><img src="https://img.shields.io/badge/all_contributors-131-pink.svg"
|
||||||
|
alt="All Contributors"/>
|
||||||
|
</a></p><p align='center'><a
|
||||||
|
href="https://twitter.com/freesewing_org"
|
||||||
|
title="Follow @freesewing_org on Twitter"
|
||||||
|
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-blue.svg?logo=twitter&logoColor=white&logoWidth=15"
|
||||||
|
alt="Follow @freesewing_org on Twitter"/>
|
||||||
|
</a><a
|
||||||
|
href="https://chat.freesewing.org"
|
||||||
|
title="Chat with us on Discord"
|
||||||
|
><img src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
|
||||||
|
alt="Chat with us on Discord"/>
|
||||||
|
</a><a
|
||||||
|
href="https://freesewing.org/patrons/join"
|
||||||
|
title="Become a FreeSewing Patron"
|
||||||
|
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
|
||||||
|
alt="Become a FreeSewing Patron"/>
|
||||||
|
</a><a
|
||||||
|
href="https://instagram.com/freesewing_org"
|
||||||
|
title="Follow @freesewing_org on Twitter"
|
||||||
|
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-E4405F.svg?logo=instagram&logoColor=white&logoWidth=15"
|
||||||
|
alt="Follow @freesewing_org on Twitter"/>
|
||||||
|
</a></p>
|
||||||
|
|
||||||
|
# @freesewing/i18n
|
||||||
|
|
||||||
|
Translation for the FreeSewing project
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# FreeSewing
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
>#### Support FreeSewing: Become a patron, or make a one-time donation 🥰
|
||||||
|
>
|
||||||
|
> FreeSewing is an open source project maintained by Joost De Cock and financially supported by the FreeSewing patrons.
|
||||||
|
>
|
||||||
|
> If you feel FreeSewing is worthwhile, and you can spend a few coins without
|
||||||
|
hardship, then you should [join us and become a patron](https://freesewing.org/community/join).
|
||||||
|
|
||||||
|
## What am I looking at? 🤔
|
||||||
|
|
||||||
|
This repository is the FreeSewing *monorepo* holding all FreeSewing's websites, documentation, designs, plugins, and other NPM packages.
|
||||||
|
|
||||||
|
This folder holds: @freesewing/i18n
|
||||||
|
|
||||||
|
If you're not entirely sure what to do or how to start, type this command:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run tips
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If you don't want to set up a dev environment, you can run it in your browser:
|
||||||
|
>
|
||||||
|
> [](https://gitpod.io/#https://github.com/freesewing/freesewing)
|
||||||
|
>
|
||||||
|
> We recommend that you fork our repository and then
|
||||||
|
> put `gitpod.io/#<entire-url-of-your-fork` into a browser
|
||||||
|
> to start up a browser-based dev environment of your own.
|
||||||
|
|
||||||
|
## About FreeSewing 💀
|
||||||
|
|
||||||
|
Where the world of makers and developers collide, that's where you'll find FreeSewing.
|
||||||
|
|
||||||
|
If you're a maker, checkout [freesewing.org](https://freesewing.org/) where you can generate
|
||||||
|
sewing patterns adapted to your measurements.
|
||||||
|
|
||||||
|
If you're a developer, the FreeSewing documentation lives at [freesewing.dev](https://freesewing.dev/).
|
||||||
|
The FreeSewing [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox
|
||||||
|
for parametric design of sewing patterns. But FreeSewing also provides a range
|
||||||
|
of [plugins](https://freesewing.dev/reference/plugins/) that further extend the
|
||||||
|
functionality of the platform.
|
||||||
|
|
||||||
|
If you have NodeJS installed, you can try it right now by running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @freesewing/new-design
|
||||||
|
```
|
||||||
|
|
||||||
|
Getting started guides are available for:
|
||||||
|
- [Linux](https://freesewing.dev/tutorials/getting-started-linux/)
|
||||||
|
- [MacOS](https://freesewing.dev/tutorials/getting-started-mac/)
|
||||||
|
- [Windows](https://freesewing.dev/tutorials/getting-started-windows/)
|
||||||
|
|
||||||
|
The [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) will
|
||||||
|
show you how to create your first parametric design.
|
||||||
|
|
||||||
|
## Getting started ⚡
|
||||||
|
|
||||||
|
To get started with FreeSewing, you can spin up our development environment with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @freesewing/new-design
|
||||||
|
```
|
||||||
|
|
||||||
|
To work with FreeSewing's monorepo, you'll need [NodeJS v20](https://nodejs.org) on your system.
|
||||||
|
Once you have that, clone (or fork) this repo and run `npm run kickstart`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone git@github.com:freesewing/freesewing.git
|
||||||
|
cd freesewing
|
||||||
|
npm run kickstart
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links 👩💻
|
||||||
|
|
||||||
|
**Official channels**
|
||||||
|
|
||||||
|
- 💻 Makers website: [FreeSewing.org](https://freesewing.org)
|
||||||
|
- 💻 Developers website: [FreeSewing.dev](https://freesewing.dev)
|
||||||
|
- ✅ [Support](https://github.com/freesewing/freesewing/issues/new/choose),
|
||||||
|
[Issues](https://github.com/freesewing/freesewing/issues) &
|
||||||
|
[Discussions](https://github.com/freesewing/freesewing/discussions) on
|
||||||
|
[GitHub](https://github.com/freesewing/freesewing)
|
||||||
|
|
||||||
|
**Social media**
|
||||||
|
|
||||||
|
- 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org)
|
||||||
|
- 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)
|
||||||
|
|
||||||
|
**Places the FreeSewing community hangs out**
|
||||||
|
|
||||||
|
- 💬 [Discord](https://discord.freesewing.org/)
|
||||||
|
- 💬 [Facebook](https://www.facebook.com/groups/627769821272714/)
|
||||||
|
- 💬 [Reddit](https://www.reddit.com/r/freesewing/)
|
||||||
|
|
||||||
|
## License: MIT 🤓
|
||||||
|
|
||||||
|
© [Joost De Cock](https://github.com/joostdecock).
|
||||||
|
See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details.
|
||||||
|
|
||||||
|
## Where to get help 🤯
|
||||||
|
|
||||||
|
For [Support](https://github.com/freesewing/freesewing/issues/new/choose),
|
||||||
|
please use the [Issues](https://github.com/freesewing/freesewing/issues) &
|
||||||
|
[Discussions](https://github.com/freesewing/freesewing/discussions) on
|
||||||
|
[GitHub](https://github.com/freesewing/freesewing).
|
||||||
|
|
4
packages/i18n/data.mjs
Normal file
4
packages/i18n/data.mjs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// This file is auto-generated | All changes you make will be overwritten.
|
||||||
|
export const name = '@freesewing/i18n'
|
||||||
|
export const version = '3.3.0-rc.1'
|
||||||
|
export const data = { name, version }
|
50
packages/i18n/package.json
Normal file
50
packages/i18n/package.json
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
"name": "@freesewing/i18n",
|
||||||
|
"version": "3.3.0-rc.1",
|
||||||
|
"description": "Translation for the FreeSewing project",
|
||||||
|
"author": "Joost De Cock <joost@joost.at> (https://github.com/joostdecock)",
|
||||||
|
"homepage": "https://freesewing.org/",
|
||||||
|
"repository": "github:freesewing/freesewing",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/freesewing/freesewing/issues"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://freesewing.org/patrons/join"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"freesewing",
|
||||||
|
"i18n",
|
||||||
|
"internationalisation",
|
||||||
|
"languages",
|
||||||
|
"localisation",
|
||||||
|
"translation"
|
||||||
|
],
|
||||||
|
"type": "module",
|
||||||
|
"module": "src/index.mjs",
|
||||||
|
"exports": {
|
||||||
|
".": "./src/index.mjs"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
|
||||||
|
"test": "echo \"i18n: No tests configured. Perhaps you could write some?\" && exit 0",
|
||||||
|
"tips": "node ../../scripts/help.mjs",
|
||||||
|
"lint": "npx eslint 'src/**' 'tests/*.mjs'"
|
||||||
|
},
|
||||||
|
"peerDependencies": {},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {},
|
||||||
|
"files": [
|
||||||
|
"src/**",
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public",
|
||||||
|
"tag": "next"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 20"
|
||||||
|
},
|
||||||
|
"private": true
|
||||||
|
}
|
3
packages/i18n/src/index.mjs
Normal file
3
packages/i18n/src/index.mjs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { measurements } from './measurements.mjs'
|
||||||
|
|
||||||
|
export { measurements }
|
40
packages/i18n/src/measurements.mjs
Normal file
40
packages/i18n/src/measurements.mjs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
export const measurements = {
|
||||||
|
ankle: 'Ankle circumference',
|
||||||
|
biceps: 'Biceps circumference',
|
||||||
|
bustFront: 'Bust front',
|
||||||
|
bustPointToUnderbust: 'Bust point to underbust',
|
||||||
|
bustSpan: 'Bust span',
|
||||||
|
chest: 'Chest circumference',
|
||||||
|
crossSeam: 'Cross seam',
|
||||||
|
crossSeamFront: 'Cross seam front',
|
||||||
|
head: 'Head circumference',
|
||||||
|
heel: 'Heel circumference',
|
||||||
|
highBustFront: 'High bust front',
|
||||||
|
highBust: 'High bust',
|
||||||
|
hips: 'Hips circumference',
|
||||||
|
hpsToBust: 'HPS to bust',
|
||||||
|
hpsToWaistBack: 'HPS to waist back',
|
||||||
|
hpsToWaistFront: 'HPS to waist front',
|
||||||
|
inseam: 'Inseam',
|
||||||
|
knee: 'Knee circumference',
|
||||||
|
neck: 'Neck circumference',
|
||||||
|
seat: 'Seat circumference',
|
||||||
|
seatBack: 'Seat back',
|
||||||
|
crotchDepth: 'Crotch depth',
|
||||||
|
shoulderSlope: 'Shoulder slope',
|
||||||
|
shoulderToElbow: 'Shoulder to elbow',
|
||||||
|
shoulderToShoulder: 'Shoulder to shoulder',
|
||||||
|
shoulderToWrist: 'Shoulder to wrist',
|
||||||
|
underbust: 'Underbust',
|
||||||
|
upperLeg: 'Upper leg circumference',
|
||||||
|
waist: 'Waist circumference',
|
||||||
|
waistBack: 'Waist back',
|
||||||
|
waistToArmpit: 'Waist to armpit',
|
||||||
|
waistToFloor: 'Waist to floor',
|
||||||
|
waistToHips: 'Waist to hips',
|
||||||
|
waistToKnee: 'Waist to knee',
|
||||||
|
waistToSeat: 'Waist to seat',
|
||||||
|
waistToUnderbust: 'Waist to underbust',
|
||||||
|
waistToUpperLeg: 'Waist to upper leg',
|
||||||
|
wrist: 'Wrist circumference',
|
||||||
|
}
|
|
@ -1,11 +1,19 @@
|
||||||
// Dependencies
|
// Dependencies
|
||||||
import { measurements, isDegreeMeasurement, control as controlConfig } from '@freesewing/config'
|
import {
|
||||||
|
measurements,
|
||||||
|
isDegreeMeasurement,
|
||||||
|
control as controlConfig,
|
||||||
|
urls,
|
||||||
|
} from '@freesewing/config'
|
||||||
|
import { measurements as measurementTranslations } from '@freesewing/i18n'
|
||||||
|
import { measurements as designMeasurements } from '@freesewing/collection'
|
||||||
import {
|
import {
|
||||||
cloudflareImageUrl,
|
cloudflareImageUrl,
|
||||||
capitalize,
|
capitalize,
|
||||||
formatMm,
|
formatMm,
|
||||||
horFlexClasses,
|
horFlexClasses,
|
||||||
linkClasses,
|
linkClasses,
|
||||||
|
notEmpty,
|
||||||
roundDistance,
|
roundDistance,
|
||||||
shortDate,
|
shortDate,
|
||||||
timeAgo,
|
timeAgo,
|
||||||
|
@ -18,8 +26,10 @@ import React, { useState, useEffect, Fragment, useContext } from 'react'
|
||||||
import { useAccount } from '@freesewing/react/hooks/useAccount'
|
import { useAccount } from '@freesewing/react/hooks/useAccount'
|
||||||
import { useBackend } from '@freesewing/react/hooks/useBackend'
|
import { useBackend } from '@freesewing/react/hooks/useBackend'
|
||||||
// Components
|
// Components
|
||||||
import { Link as WebLink } from '@freesewing/react/components/Link'
|
import { Link as WebLink, AnchorLink } from '@freesewing/react/components/Link'
|
||||||
import {
|
import {
|
||||||
|
BoolNoIcon,
|
||||||
|
BoolYesIcon,
|
||||||
CloneIcon,
|
CloneIcon,
|
||||||
CuratedMeasurementsSetIcon,
|
CuratedMeasurementsSetIcon,
|
||||||
EditIcon,
|
EditIcon,
|
||||||
|
@ -36,54 +46,26 @@ import {
|
||||||
// BoolNoIcon,
|
// BoolNoIcon,
|
||||||
} from '@freesewing/react/components/Icon'
|
} from '@freesewing/react/components/Icon'
|
||||||
import { BookmarkButton, MsetCard } from '@freesewing/react/components/Account'
|
import { BookmarkButton, MsetCard } from '@freesewing/react/components/Account'
|
||||||
import { ToggleInput } from '@freesewing/react/components/Input'
|
import {
|
||||||
|
DesignInput,
|
||||||
|
MarkdownInput,
|
||||||
|
ListInput,
|
||||||
|
MeasieInput,
|
||||||
|
PassiveImageInput,
|
||||||
|
StringInput,
|
||||||
|
ToggleInput,
|
||||||
|
} from '@freesewing/react/components/Input'
|
||||||
import { DisplayRow } from './shared.mjs'
|
import { DisplayRow } from './shared.mjs'
|
||||||
import Markdown from 'react-markdown'
|
import Markdown from 'react-markdown'
|
||||||
import { ModalWrapper } from '@freesewing/react/components/Modal'
|
import { ModalWrapper } from '@freesewing/react/components/Modal'
|
||||||
import { Json } from '@freesewing/react/components/Json'
|
import { Json } from '@freesewing/react/components/Json'
|
||||||
import { Yaml } from '@freesewing/react/components/Yaml'
|
import { Yaml } from '@freesewing/react/components/Yaml'
|
||||||
|
import { Popout } from '@freesewing/react/components/Popout'
|
||||||
|
|
||||||
//import { measurements as designMeasurements } from 'shared/prebuild/data/design-measurements.mjs'
|
const t = (input) => {
|
||||||
//import { freeSewingConfig as conf, controlLevels } from 'shared/config/freesewing.config.mjs'
|
console.log('t called', input)
|
||||||
//import { isDegreeMeasurement } from 'config/measurements.mjs'
|
return input
|
||||||
//import {
|
}
|
||||||
// shortDate,
|
|
||||||
// cloudflareImageUrl,
|
|
||||||
// formatMm,
|
|
||||||
// hasRequiredMeasurements,
|
|
||||||
// capitalize,
|
|
||||||
// horFlexClasses,
|
|
||||||
//} from 'shared/utils.mjs'
|
|
||||||
//// Hooks
|
|
||||||
//import { useState, useEffect, useContext } from 'react'
|
|
||||||
//import { useTranslation } from 'next-i18next'
|
|
||||||
//import { useAccount } from 'shared/hooks/use-account.mjs'
|
|
||||||
//import { useBackend } from 'shared/hooks/use-backend.mjs'
|
|
||||||
//import { useRouter } from 'next/router'
|
|
||||||
//// Context
|
|
||||||
//import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
|
||||||
//import { ModalContext } from 'shared/context/modal-context.mjs'
|
|
||||||
//// Components
|
|
||||||
//import { Popout } from 'shared/components/popout/index.mjs'
|
|
||||||
//import { BackToAccountButton } from './shared.mjs'
|
|
||||||
//import { AnchorLink, PageLink, Link } from 'shared/components/link.mjs'
|
|
||||||
//import { Json } from 'shared/components/json.mjs'
|
|
||||||
//import { Yaml } from 'shared/components/yaml.mjs'
|
|
||||||
//import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
|
||||||
//import { Mdx } from 'shared/components/mdx/dynamic.mjs'
|
|
||||||
//import Timeago from 'react-timeago'
|
|
||||||
//import {
|
|
||||||
// StringInput,
|
|
||||||
// ToggleInput,
|
|
||||||
// PassiveImageInput,
|
|
||||||
// ListInput,
|
|
||||||
// MarkdownInput,
|
|
||||||
// MeasieInput,
|
|
||||||
// DesignDropdown,
|
|
||||||
// ns as inputNs,
|
|
||||||
//} from 'shared/components/inputs.mjs'
|
|
||||||
//import { BookmarkButton } from 'shared/components/bookmarks.mjs'
|
|
||||||
//import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Component to show an individual measurements set
|
* Component to show an individual measurements set
|
||||||
|
@ -163,10 +145,8 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
}
|
}
|
||||||
}, [id, publicOnly])
|
}, [id, publicOnly])
|
||||||
|
|
||||||
const filterMeasurements = () => {
|
const filterMeasurements = () =>
|
||||||
if (!filter) return measurements.map((m) => `measurements:${m}` + `|${m}`).sort()
|
filter ? designMeasurements[filter].sort() : measurements.sort()
|
||||||
else return designMeasurements[filter].map((m) => `measurements:${m}` + `|${m}`).sort()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!id || !mset) return null
|
if (!id || !mset) return null
|
||||||
|
|
||||||
|
@ -192,7 +172,7 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
setLoadingStatus([true, 'Saving measurements set'])
|
setLoadingStatus([true, 'Saving measurements set'])
|
||||||
const [status, body] = await backend.updateSet(mset.id, data)
|
const [status, body] = await backend.updateSet(mset.id, data)
|
||||||
if (status === 200 && body.result === 'success') {
|
if (status === 200 && body.result === 'success') {
|
||||||
setMset(body.data.set)
|
setMset(body.set)
|
||||||
setEdit(false)
|
setEdit(false)
|
||||||
setLoadingStatus([true, 'Nailed it', true, true])
|
setLoadingStatus([true, 'Nailed it', true, true])
|
||||||
} else
|
} else
|
||||||
|
@ -218,10 +198,9 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
}
|
}
|
||||||
delete data.img
|
delete data.img
|
||||||
const [status, body] = await backend.createSet(data)
|
const [status, body] = await backend.createSet(data)
|
||||||
if (status === 200 && body.result === 'success') {
|
if (status === 201 && body.result === 'created') {
|
||||||
setMset(body.data.set)
|
setLoadingStatus([true, 'Loading newly created set', true, true])
|
||||||
setEdit(false)
|
window.location = `/account/set/?id=${body.set.id}`
|
||||||
setLoadingStatus([true, 'Nailed it', true, true])
|
|
||||||
} else setLoadingStatus([true, 'We failed to create this measurements set', true, false])
|
} else setLoadingStatus([true, 'We failed to create this measurements set', true, false])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,14 +214,14 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
{account.control > 2 && mset.public && mset.userId !== account.id ? (
|
{account.control > 2 && mset.public && mset.userId !== account.id ? (
|
||||||
<div className="flex flex-row gap-2 items-center">
|
<div className="flex flex-row gap-2 items-center">
|
||||||
<a
|
<a
|
||||||
className="badge badge-secondary font-bold badge-lg"
|
className="daisy-badge daisy-badge-secondary font-bold daisy-badge-lg"
|
||||||
href={`${conf.backend}/sets/${mset.id}.json`}
|
href={`${urls.backend}/sets/${mset.id}.json`}
|
||||||
>
|
>
|
||||||
JSON
|
JSON
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className="badge badge-success font-bold badge-lg"
|
className="daisy-badge daisy-badge-success font-bold daisy-badge-lg"
|
||||||
href={`${conf.backend}/sets/${mset.id}.yaml`}
|
href={`${urls.backend}/sets/${mset.id}.yaml`}
|
||||||
>
|
>
|
||||||
YAML
|
YAML
|
||||||
</a>
|
</a>
|
||||||
|
@ -253,7 +232,7 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
{account.control > 3 && mset.userId === account.id ? (
|
{account.control > 3 && mset.userId === account.id ? (
|
||||||
<div className="flex flex-row gap-2 items-center">
|
<div className="flex flex-row gap-2 items-center">
|
||||||
<button
|
<button
|
||||||
className="badge badge-secondary font-bold badge-lg"
|
className="daisy-badge daisy-badge-secondary font-bold daisy-badge-lg"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setModal(
|
setModal(
|
||||||
<ModalWrapper keepOpenOnClick>
|
<ModalWrapper keepOpenOnClick>
|
||||||
|
@ -265,7 +244,7 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
JSON
|
JSON
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="badge badge-success font-bold badge-lg"
|
className="daisy-badge daisy-badge-success font-bold daisy-badge-lg text-neutral-content"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setModal(
|
setModal(
|
||||||
<ModalWrapper keepOpenOnClick>
|
<ModalWrapper keepOpenOnClick>
|
||||||
|
@ -283,12 +262,12 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
{account.id && account.control > 2 && mset.public && mset.userId !== account.id ? (
|
{account.id && account.control > 2 && mset.public && mset.userId !== account.id ? (
|
||||||
<button
|
<button
|
||||||
className="daisy-btn daisy-btn-primary"
|
className="daisy-btn daisy-btn-primary"
|
||||||
title={t('account:importSet')}
|
title="Import measurements set"
|
||||||
onClick={importSet}
|
onClick={importSet}
|
||||||
>
|
>
|
||||||
<div className="flex flex-row gap-4 justify-between items-center w-full">
|
<div className="flex flex-row gap-4 justify-between items-center w-full">
|
||||||
<UploadIcon />
|
<UploadIcon />
|
||||||
{t('account:importSet')}
|
Import measurements set
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -379,7 +358,7 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
return (
|
return (
|
||||||
<div className="max-w-2xl">
|
<div className="max-w-2xl">
|
||||||
{heading}
|
{heading}
|
||||||
<SuggestCset {...{ mset, setLoadingStatus, backend, t }} />
|
<SuggestCset {...{ mset, setLoadingStatus, backend, Link }} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -466,56 +445,27 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
return (
|
return (
|
||||||
<div className="max-w-2xl">
|
<div className="max-w-2xl">
|
||||||
{heading}
|
{heading}
|
||||||
<ul className="list list-disc list-inside ml-4">
|
<h2 id="measies">Measurements</h2>
|
||||||
{['measies', 'data'].map((s) => (
|
|
||||||
<li key={s}>
|
|
||||||
<AnchorLink id={s}>{s}</AnchorLink>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
<ul className="list list-disc list-inside ml-4">
|
|
||||||
<li>
|
|
||||||
<AnchorLink id="name">Name</AnchorLink>
|
|
||||||
</li>
|
|
||||||
{account.control >= conf.account.sets.img ? (
|
|
||||||
<li>
|
|
||||||
<AnchorLink id="image">Image</AnchorLink>
|
|
||||||
</li>
|
|
||||||
) : null}
|
|
||||||
{['public', 'units', 'notes'].map((id) =>
|
|
||||||
account.control >= conf.account.sets[id] ? (
|
|
||||||
<li key={id}>
|
|
||||||
<AnchorLink id="units">{id}</AnchorLink>
|
|
||||||
</li>
|
|
||||||
) : null
|
|
||||||
)}
|
|
||||||
</ul>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2 id="measies">{t('measies')}</h2>
|
|
||||||
<div className="bg-secondary px-4 pt-1 pb-4 rounded-lg shadow bg-opacity-10">
|
<div className="bg-secondary px-4 pt-1 pb-4 rounded-lg shadow bg-opacity-10">
|
||||||
<DesignDropdown
|
<DesignInput
|
||||||
update={setFilter}
|
update={setFilter}
|
||||||
label="Filter by design"
|
label="Filter by design"
|
||||||
current={filter}
|
current={filter}
|
||||||
firstOption={<option value="">Clear filter</option>}
|
firstOption={<option value="">Clear filter</option>}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{filterMeasurements().map((mplus) => {
|
{filterMeasurements().map((m) => (
|
||||||
const [translated, m] = mplus.split('|')
|
<MeasieInput
|
||||||
|
id={`measie-${m}`}
|
||||||
return (
|
key={m}
|
||||||
<MeasieInput
|
m={m}
|
||||||
id={`measie-${m}`}
|
imperial={mset.imperial}
|
||||||
key={m}
|
label={measurementTranslations[m]}
|
||||||
m={m}
|
current={mset.measies[m]}
|
||||||
imperial={mset.imperial}
|
original={mset.measies[m]}
|
||||||
label={translated}
|
update={updateMeasies}
|
||||||
current={mset.measies[m]}
|
/>
|
||||||
original={mset.measies[m]}
|
))}
|
||||||
update={updateMeasies}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
|
|
||||||
<h2 id="data">Data</h2>
|
<h2 id="data">Data</h2>
|
||||||
|
|
||||||
|
@ -533,7 +483,7 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
|
|
||||||
{/* img: Control level determines whether or not to show this */}
|
{/* img: Control level determines whether or not to show this */}
|
||||||
<span id="image"></span>
|
<span id="image"></span>
|
||||||
{account.control >= conf.account.sets.img ? (
|
{account.control >= controlConfig.account.sets.img ? (
|
||||||
<PassiveImageInput
|
<PassiveImageInput
|
||||||
id="set-img"
|
id="set-img"
|
||||||
label="Image"
|
label="Image"
|
||||||
|
@ -545,7 +495,7 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
|
|
||||||
{/* public: Control level determines whether or not to show this */}
|
{/* public: Control level determines whether or not to show this */}
|
||||||
<span id="public"></span>
|
<span id="public"></span>
|
||||||
{account.control >= conf.account.sets.public ? (
|
{account.control >= controlConfig.account.sets.public ? (
|
||||||
<ListInput
|
<ListInput
|
||||||
id="set-public"
|
id="set-public"
|
||||||
label="Public"
|
label="Public"
|
||||||
|
@ -581,7 +531,7 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
|
|
||||||
{/* units: Control level determines whether or not to show this */}
|
{/* units: Control level determines whether or not to show this */}
|
||||||
<span id="units"></span>
|
<span id="units"></span>
|
||||||
{account.control >= conf.account.sets.units ? (
|
{account.control >= controlConfig.account.sets.units ? (
|
||||||
<>
|
<>
|
||||||
<ListInput
|
<ListInput
|
||||||
id="set-units"
|
id="set-units"
|
||||||
|
@ -611,13 +561,15 @@ export const Set = ({ id, publicOnly = false, Link = false }) => {
|
||||||
]}
|
]}
|
||||||
current={imperial}
|
current={imperial}
|
||||||
/>
|
/>
|
||||||
<span className="text-large text-warning">{t('unitsMustSave')}</span>
|
<span className="text-large text-warning">
|
||||||
|
Note: You must save after changing Units to have the change take effect on this page.
|
||||||
|
</span>
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{/* notes: Control level determines whether or not to show this */}
|
{/* notes: Control level determines whether or not to show this */}
|
||||||
<span id="notes"></span>
|
<span id="notes"></span>
|
||||||
{account.control >= conf.account.sets.notes ? (
|
{account.control >= controlConfig.account.sets.notes ? (
|
||||||
<MarkdownInput
|
<MarkdownInput
|
||||||
id="set-notes"
|
id="set-notes"
|
||||||
label="Notes"
|
label="Notes"
|
||||||
|
@ -652,14 +604,137 @@ export const MeasurementValue = ({ val, m, imperial = false }) =>
|
||||||
<span dangerouslySetInnerHTML={{ __html: formatMm(val, imperial) }}></span>
|
<span dangerouslySetInnerHTML={{ __html: formatMm(val, imperial) }}></span>
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* React component to suggest a measurements set for curation
|
||||||
|
*
|
||||||
|
* @param {object} props - All React props
|
||||||
|
* @param {string} mset - The measurements set
|
||||||
|
*/
|
||||||
|
export const SuggestCset = ({ mset, Link }) => {
|
||||||
|
// State
|
||||||
|
const [height, setHeight] = useState('')
|
||||||
|
const [img, setImg] = useState('')
|
||||||
|
const [name, setName] = useState('')
|
||||||
|
const [notes, setNotes] = useState('')
|
||||||
|
const [submission, setSubmission] = useState(false)
|
||||||
|
|
||||||
|
console.log(mset)
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
const backend = useBackend()
|
||||||
|
|
||||||
|
// Method to submit the form
|
||||||
|
const suggestSet = async () => {
|
||||||
|
setLoadingStatus([true, 'Contacting backend'])
|
||||||
|
const result = await backend.suggestCset({ set: mset.id, height, img, name, notes })
|
||||||
|
if (result.success && result.data.submission) {
|
||||||
|
setSubmission(result.data.submission)
|
||||||
|
setLoadingStatus([true, 'Nailed it', true, true])
|
||||||
|
} else setLoadingStatus([true, 'An unexpected error occured. Please report this.', true, false])
|
||||||
|
}
|
||||||
|
|
||||||
|
const missing = []
|
||||||
|
for (const m of measurements) {
|
||||||
|
if (typeof mset.measies[m] === 'undefined') missing.push(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submission) {
|
||||||
|
const url = `/curate/sets/suggested/${submission.id}`
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2>Thank you</h2>
|
||||||
|
<p>Your submission has been registered and will be processed by one of our curators.</p>
|
||||||
|
<p>
|
||||||
|
It is available at: <Link href={url}>{url}</Link>
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2>Suggest a measurements set for curation</h2>
|
||||||
|
<h4 className="flex flex-row items-center gap-2">
|
||||||
|
{missing.length > 0 ? <BoolNoIcon /> : <BoolYesIcon />}
|
||||||
|
Measurements
|
||||||
|
</h4>
|
||||||
|
{missing.length > 0 ? (
|
||||||
|
<>
|
||||||
|
<p>
|
||||||
|
To ensure curated measurements sets work for all designs, you need to provide a full set
|
||||||
|
of measurements.
|
||||||
|
</p>
|
||||||
|
<p>Your measurements set is missing the following measurements:</p>
|
||||||
|
<ul className="list list-inside list-disc ml-4">
|
||||||
|
{missing.map((m) => (
|
||||||
|
<li key={m}>{m}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<p>All measurements are available.</p>
|
||||||
|
)}
|
||||||
|
<h4 className="flex flex-row items-center gap-2">
|
||||||
|
{name.length > 1 ? <BoolYesIcon /> : <BoolNoIcon />}
|
||||||
|
Name
|
||||||
|
</h4>
|
||||||
|
<p>Each curated set has a name. You can suggest your own name or a pseudonym.</p>
|
||||||
|
<StringInput label="Name" current={name} update={setName} valid={(val) => val.length > 1} />
|
||||||
|
<h4 className="flex flex-row items-center gap-2">
|
||||||
|
{height.length > 1 ? <BoolYesIcon /> : <BoolNoIcon />}
|
||||||
|
Height
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
To allow organizing and presenting our curated sets in a structured way, we organize them by
|
||||||
|
height.
|
||||||
|
</p>
|
||||||
|
<StringInput
|
||||||
|
label="height"
|
||||||
|
current={height}
|
||||||
|
update={setHeight}
|
||||||
|
valid={(val) => val.length > 1}
|
||||||
|
/>
|
||||||
|
<h4 className="flex flex-row items-center gap-2 mt-4">
|
||||||
|
{img.length > 0 ? <BoolYesIcon /> : <BoolNoIcon />}
|
||||||
|
Image
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Finally, we need a picture. Please refer to the documentation to see what makes a good
|
||||||
|
picture for a curated measurements set.
|
||||||
|
<Link href="/docs/about/site/csets">Documentation</Link>
|
||||||
|
</p>
|
||||||
|
<PassiveImageInput
|
||||||
|
label="Image"
|
||||||
|
current={img}
|
||||||
|
update={setImg}
|
||||||
|
valid={(val) => val.length > 1}
|
||||||
|
/>
|
||||||
|
<h4 className="flex flex-row items-center gap-2 mt-4">
|
||||||
|
<BoolYesIcon />
|
||||||
|
Notes
|
||||||
|
</h4>
|
||||||
|
<p>If you would like to add any notes, you can do so here.</p>
|
||||||
|
<Popout tip compact>
|
||||||
|
This field supports markdown
|
||||||
|
</Popout>
|
||||||
|
<MarkdownInput label="Notes" current={notes} update={setNotes} valid={() => true} />
|
||||||
|
<button
|
||||||
|
className="daisy-btn daisy-btn-primary w-full mt-4"
|
||||||
|
disabled={!(missing.length === 0 && height.length > 1 && img.length > 0)}
|
||||||
|
onClick={suggestSet}
|
||||||
|
>
|
||||||
|
Suggest for curation
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const NewSet = () => {
|
export const NewSet = () => {
|
||||||
// Hooks
|
// Hooks
|
||||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
|
||||||
const backend = useBackend()
|
const backend = useBackend()
|
||||||
const { t } = useTranslation(ns)
|
|
||||||
const router = useRouter()
|
|
||||||
const { account } = useAccount()
|
const { account } = useAccount()
|
||||||
|
const { setLoadingStatus, LoadingProgress } = useContext(LoadingStatusContext)
|
||||||
|
|
||||||
// State
|
// State
|
||||||
const [name, setName] = useState('')
|
const [name, setName] = useState('')
|
||||||
|
@ -669,39 +744,46 @@ export const NewSet = () => {
|
||||||
|
|
||||||
// Helper method to create a new set
|
// Helper method to create a new set
|
||||||
const createSet = async () => {
|
const createSet = async () => {
|
||||||
setLoadingStatus([true, 'processingUpdate'])
|
setLoadingStatus([true, 'Storing new measurements set'])
|
||||||
const result = await backend.createSet({ name, imperial })
|
const [status, body] = await backend.createSet({ name, imperial })
|
||||||
if (result.success) {
|
if (status === 201 && body.result === 'created') {
|
||||||
setLoadingStatus([true, t('nailedIt'), true, true])
|
setLoadingStatus([true, 'Nailed it', true, true])
|
||||||
router.push(`/account/set?id=${result.data.set.id}`)
|
window.location = `/account/set?id=${body.set.id}`
|
||||||
} else setLoadingStatus([true, 'backendError', true, false])
|
} else
|
||||||
|
setLoadingStatus([
|
||||||
|
true,
|
||||||
|
'Failed to save the measurments set. Please report this.',
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-xl">
|
<div className="max-w-xl">
|
||||||
<h5>{t('name')}</h5>
|
<h5>Name</h5>
|
||||||
<p>{t('setNameDesc')}</p>
|
<p>Give this set of measurements a name. That will help tell them apart.</p>
|
||||||
<input
|
<StringInput
|
||||||
autoFocus
|
id="new-set"
|
||||||
value={name}
|
label="Name"
|
||||||
onChange={(evt) => setName(evt.target.value)}
|
update={setName}
|
||||||
className="input w-full input-bordered flex flex-row"
|
current={name}
|
||||||
type="text"
|
valid={(val) => val && val.length > 0}
|
||||||
placeholder={'Georg Cantor'}
|
placeholder={'Georg Cantor'}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-row gap-2 items-center w-full mt-8 mb-2">
|
<div className="flex flex-row gap-2 items-center w-full mt-8 mb-2">
|
||||||
<button
|
<button
|
||||||
className="btn btn-primary grow capitalize"
|
className="daisy-btn daisy-btn-primary grow capitalize"
|
||||||
disabled={name.length < 1}
|
disabled={name.length < 1}
|
||||||
onClick={createSet}
|
onClick={createSet}
|
||||||
>
|
>
|
||||||
{t('newSet')}
|
New Measurements Set
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
export const SetCard = ({
|
export const SetCard = ({
|
||||||
set,
|
set,
|
||||||
|
@ -950,122 +1032,5 @@ export const BookmarkedSetPicker = ({ design, clickHandler, t, size, href }) =>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const SuggestCset = ({ mset, backend, setLoadingStatus, t }) => {
|
|
||||||
// State
|
|
||||||
const [height, setHeight] = useState('')
|
|
||||||
const [img, setImg] = useState('')
|
|
||||||
const [name, setName] = useState('')
|
|
||||||
const [notes, setNotes] = useState('')
|
|
||||||
const [submission, setSubmission] = useState(false)
|
|
||||||
|
|
||||||
// Method to submit the form
|
|
||||||
const suggestSet = async () => {
|
|
||||||
setLoadingStatus([true, 'status:contactingBackend'])
|
|
||||||
const result = await backend.suggestCset({ set: mset.id, height, img, name, notes })
|
|
||||||
if (result.success && result.data.submission) {
|
|
||||||
setSubmission(result.data.submission)
|
|
||||||
setLoadingStatus([true, 'status:nailedIt', true, true])
|
|
||||||
} else setLoadingStatus([true, 'backendError', true, false])
|
|
||||||
}
|
|
||||||
|
|
||||||
const missing = []
|
|
||||||
for (const m of measurements) {
|
|
||||||
if (typeof mset.measies[m] === 'undefined') missing.push(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submission) {
|
|
||||||
const url = `/curate/sets/suggested/${submission.id}`
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h2>{t('account:thankYouVeryMuch')}</h2>
|
|
||||||
<p>{t('account:csetSuggestedMsg')}</p>
|
|
||||||
<p>
|
|
||||||
{t('account:itIsAvailableAt')}: <PageLink href={url} txt={url} />
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h2>{t('account:suggestCset')}</h2>
|
|
||||||
<h4 className="flex flex-row items-center gap-2">
|
|
||||||
{missing.length > 0 ? <BoolNoIcon /> : <BoolYesIcon />}
|
|
||||||
{t('account:measurements')}
|
|
||||||
</h4>
|
|
||||||
{missing.length > 0 ? (
|
|
||||||
<>
|
|
||||||
<p>{t('account:csetAllMeasies')}</p>
|
|
||||||
<p>{t('account:csetMissing')}:</p>
|
|
||||||
<ul className="list list-inside list-disc ml-4">
|
|
||||||
{missing.map((m) => (
|
|
||||||
<li key={m}>{t(`measurements:${m}`)}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<p>{t('account:allMeasiesAvailable')}</p>
|
|
||||||
)}
|
|
||||||
<h4 className="flex flex-row items-center gap-2">
|
|
||||||
{name.length > 1 ? <BoolYesIcon /> : <BoolNoIcon />}
|
|
||||||
{t('account:name')}
|
|
||||||
</h4>
|
|
||||||
<p>{t('account:csetNameMsg')}</p>
|
|
||||||
<StringInput
|
|
||||||
label={t('account:name')}
|
|
||||||
current={name}
|
|
||||||
update={setName}
|
|
||||||
valid={(val) => val.length > 1}
|
|
||||||
/>
|
|
||||||
<h4 className="flex flex-row items-center gap-2">
|
|
||||||
{height.length > 1 ? <BoolYesIcon /> : <BoolNoIcon />}
|
|
||||||
{t('measurements:height')}
|
|
||||||
</h4>
|
|
||||||
<p>{t('account:csetHeightMsg1')}</p>
|
|
||||||
<StringInput
|
|
||||||
label={t('measurements:height')}
|
|
||||||
current={height}
|
|
||||||
update={setHeight}
|
|
||||||
valid={(val) => val.length > 1}
|
|
||||||
/>
|
|
||||||
<h4 className="flex flex-row items-center gap-2 mt-4">
|
|
||||||
{img.length > 0 ? <BoolYesIcon /> : <BoolNoIcon />}
|
|
||||||
{t('account:img')}
|
|
||||||
</h4>
|
|
||||||
<p>
|
|
||||||
{t('account:csetImgMsg')}:{' '}
|
|
||||||
<PageLink href="/docs/about/site/csets">{t('account:docs')}</PageLink>
|
|
||||||
</p>
|
|
||||||
<PassiveImageInput
|
|
||||||
label={t('account:img')}
|
|
||||||
current={img}
|
|
||||||
update={setImg}
|
|
||||||
valid={(val) => val.length > 1}
|
|
||||||
/>
|
|
||||||
<h4 className="flex flex-row items-center gap-2 mt-4">
|
|
||||||
<BoolYesIcon />
|
|
||||||
{t('account:notes')}
|
|
||||||
</h4>
|
|
||||||
<p>{t('account:csetNotesMsg')}</p>
|
|
||||||
<Popout tip compact>
|
|
||||||
{t('account:mdSupport')}
|
|
||||||
</Popout>
|
|
||||||
<MarkdownInput
|
|
||||||
label={t('account:notes')}
|
|
||||||
current={notes}
|
|
||||||
update={setNotes}
|
|
||||||
valid={() => true}
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
className="btn btn-primary w-full mt-4"
|
|
||||||
disabled={!(missing.length === 0 && height.length > 1 && img.length > 0)}
|
|
||||||
onClick={suggestSet}
|
|
||||||
>
|
|
||||||
{t('account:suggestForCuration')}
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
|
|
||||||
import { Bookmarks, BookmarkButton } from './Bookmarks.mjs'
|
import { Bookmarks, BookmarkButton } from './Bookmarks.mjs'
|
||||||
import { Links } from './Links.mjs'
|
import { Links } from './Links.mjs'
|
||||||
import { Set } from './Set.mjs'
|
import { Set, NewSet } from './Set.mjs'
|
||||||
import { Sets, MsetCard } from './Sets.mjs'
|
import { Sets, MsetCard } from './Sets.mjs'
|
||||||
|
|
||||||
export { Bookmarks, BookmarkButton, Links, Set, Sets, MsetCard }
|
export { Bookmarks, BookmarkButton, Links, Set, NewSet, Sets, MsetCard }
|
||||||
|
|
|
@ -1,26 +1,34 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useContext, useState } from 'react'
|
||||||
import ReactDOMServer from 'react-dom/server'
|
import ReactDOMServer from 'react-dom/server'
|
||||||
import { CopyIcon, OkIcon } from '@freesewing/react/components/Icon'
|
import { CopyIcon, OkIcon } from '@freesewing/react/components/Icon'
|
||||||
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
|
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
|
||||||
|
import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus'
|
||||||
|
|
||||||
const strip = (html) =>
|
const strip = (html) =>
|
||||||
typeof DOMParser === 'undefined'
|
typeof DOMParser === 'undefined'
|
||||||
? html
|
? html
|
||||||
: new DOMParser().parseFromString(html, 'text/html').body.textContent || ''
|
: new DOMParser().parseFromString(html, 'text/html').body.textContent || ''
|
||||||
|
|
||||||
const handleCopied = (setCopied) => {
|
const handleCopied = (setCopied, setLoadingStatus, label) => {
|
||||||
setCopied(true)
|
setCopied(true)
|
||||||
|
setLoadingStatus([
|
||||||
|
true,
|
||||||
|
label ? `${label} copied to clipboard` : 'Copied to clipboard',
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
])
|
||||||
setTimeout(() => setCopied(false), 1000)
|
setTimeout(() => setCopied(false), 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CopyToClipboard = ({ content }) => {
|
export const CopyToClipboard = ({ content, label = false }) => {
|
||||||
const [copied, setCopied] = useState(false)
|
const [copied, setCopied] = useState(false)
|
||||||
|
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||||
|
|
||||||
const text =
|
const text =
|
||||||
typeof content === 'string' ? content : strip(ReactDOMServer.renderToStaticMarkup(content))
|
typeof content === 'string' ? content : strip(ReactDOMServer.renderToStaticMarkup(content))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Copy text={text} onCopy={() => handleCopied(setCopied)}>
|
<Copy text={text} onCopy={() => handleCopied(setCopied, setLoadingStatus, label)}>
|
||||||
<button className={copied ? 'text-success' : ''}>
|
<button className={copied ? 'text-success' : ''}>
|
||||||
{copied ? (
|
{copied ? (
|
||||||
<OkIcon className="w-5 h-5 text-success-content bg-success rounded-full p-1" stroke={4} />
|
<OkIcon className="w-5 h-5 text-success-content bg-success rounded-full p-1" stroke={4} />
|
||||||
|
|
|
@ -1,25 +1,41 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { CopyToClipboard } from '@freesewing/react/components/CopyToClipboard'
|
import { CopyToClipboard } from '@freesewing/react/components/CopyToClipboard'
|
||||||
|
|
||||||
const names = {
|
const defaultTitles = {
|
||||||
js: 'Javascript',
|
js: 'Javascript',
|
||||||
bash: 'Bash prompt',
|
bash: 'Bash commands',
|
||||||
sh: 'Shell prompt',
|
sh: 'Shell commands',
|
||||||
json: 'JSON',
|
json: 'JSON',
|
||||||
yaml: 'file.yaml',
|
yaml: 'YAML',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Highlight = (props) => {
|
/**
|
||||||
let language = 'txt'
|
* A React component to highlight code
|
||||||
if (props.language) language = props.language
|
*
|
||||||
if (props.children?.props?.className) {
|
* @params {object} props - All React props
|
||||||
language = props.children.props.className.split('-').pop()
|
* @params {string} language - The language to highlight
|
||||||
|
* @params {object} children - The React children
|
||||||
|
* @params {bool} raw - Set this to true to not escape tags
|
||||||
|
* @params {string} title - Title for the highlight
|
||||||
|
* @params {string} copy - Content to copy to clipboard
|
||||||
|
*/
|
||||||
|
export const Highlight = ({
|
||||||
|
language = 'txt',
|
||||||
|
children,
|
||||||
|
raw = false,
|
||||||
|
title = false,
|
||||||
|
copy = false,
|
||||||
|
}) => {
|
||||||
|
if (children?.props?.className) {
|
||||||
|
language = children.props.className.split('-').pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
const preProps = {
|
const preProps = {
|
||||||
className: `language-${language} hljs text-base lg:text-lg whitespace-break-spaces overflow-scroll pr-4`,
|
className: `language-${language} hljs text-base lg:text-lg whitespace-break-spaces overflow-scroll pr-4`,
|
||||||
}
|
}
|
||||||
if (props.raw) preProps.dangerouslySetInnerHTML = { __html: props.raw }
|
if (raw) preProps.dangerouslySetInnerHTML = { __html: raw }
|
||||||
|
|
||||||
|
const label = title ? title : defaultTitles[language] ? defaultTitles[language] : language
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hljs my-4">
|
<div className="hljs my-4">
|
||||||
|
@ -31,10 +47,10 @@ export const Highlight = (props) => {
|
||||||
px-4 py-1 mb-2 lg:text-sm
|
px-4 py-1 mb-2 lg:text-sm
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<span>{props.title ? props.title : names[language] ? names[language] : language}</span>
|
<span>{label}</span>
|
||||||
<CopyToClipboard content={props.children} />
|
<CopyToClipboard content={copy ? copy : children} label={label} />
|
||||||
</div>
|
</div>
|
||||||
<pre {...preProps}>{props.children}</pre>
|
<pre {...preProps}>{children}</pre>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,11 @@ import React, { useState, useCallback, useContext } from 'react'
|
||||||
import { useDropzone } from 'react-dropzone'
|
import { useDropzone } from 'react-dropzone'
|
||||||
import { useBackend } from '@freesewing/react/hooks/useBackend'
|
import { useBackend } from '@freesewing/react/hooks/useBackend'
|
||||||
// Components
|
// Components
|
||||||
//import { Mdx } from 'shared/components/mdx/dynamic.mjs'
|
import { ResetIcon, UploadIcon } from '@freesewing/react/components/Icon'
|
||||||
import { ResetIcon, DocsIcon, UploadIcon } from '@freesewing/react/components/Icon'
|
|
||||||
import { ModalWrapper } from '@freesewing/react/components/Modal'
|
import { ModalWrapper } from '@freesewing/react/components/Modal'
|
||||||
import { isDegreeMeasurement } from '@freesewing/config'
|
import { isDegreeMeasurement } from '@freesewing/config'
|
||||||
import { Tabs, Tab } from '@freesewing/react/components/Tab'
|
import { Tabs, Tab } from '@freesewing/react/components/Tab'
|
||||||
|
import Markdown from 'react-markdown'
|
||||||
export const ns = ['account', 'measurements', 'designs']
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper component to display a tab heading
|
* Helper component to display a tab heading
|
||||||
|
@ -32,8 +30,8 @@ export const _Tab = ({
|
||||||
setActiveTab, // Method to set the active tab
|
setActiveTab, // Method to set the active tab
|
||||||
}) => (
|
}) => (
|
||||||
<button
|
<button
|
||||||
className={`text-lg font-bold capitalize tab tab-bordered grow
|
className={`text-lg font-bold capitalize daisy-tab daisy-tab-bordered grow
|
||||||
${activeTab === id ? 'tab-active' : ''}`}
|
${activeTab === id ? 'daisy-tab-active' : ''}`}
|
||||||
onClick={() => setActiveTab(id)}
|
onClick={() => setActiveTab(id)}
|
||||||
>
|
>
|
||||||
{label ? label : id}
|
{label ? label : id}
|
||||||
|
@ -46,42 +44,16 @@ export const _Tab = ({
|
||||||
export const FormControl = ({
|
export const FormControl = ({
|
||||||
label, // the (top-left) label
|
label, // the (top-left) label
|
||||||
children, // Children to go inside the form control
|
children, // Children to go inside the form control
|
||||||
docs = false, // Optional top-right label
|
|
||||||
labelBL = false, // Optional bottom-left label
|
labelBL = false, // Optional bottom-left label
|
||||||
labelBR = false, // Optional bottom-right label
|
labelBR = false, // Optional bottom-right label
|
||||||
forId = false, // ID of the for element we are wrapping
|
forId = false, // ID of the for element we are wrapping
|
||||||
}) => {
|
}) => {
|
||||||
const { setModal } = useContext(ModalContext)
|
|
||||||
|
|
||||||
if (labelBR && !labelBL) labelBL = <span></span>
|
if (labelBR && !labelBL) labelBL = <span></span>
|
||||||
|
|
||||||
const topLabelChildren = (
|
const topLabelChildren = (
|
||||||
<>
|
<span className="daisy-label-text text-sm lg:text-base font-bold mb-1 text-inherit">
|
||||||
<span className="daisy-label-text text-sm lg:text-base font-bold mb-1 text-inherit">
|
{label}
|
||||||
{label}
|
</span>
|
||||||
</span>
|
|
||||||
{docs ? (
|
|
||||||
<span className="daisy-label-text-alt">
|
|
||||||
<button
|
|
||||||
className="daisy-btn daisy-btn-ghost daisy-btn-sm daisy-btn-circle hover:daisy-btn-secondary"
|
|
||||||
onClick={() =>
|
|
||||||
setModal(
|
|
||||||
<ModalWrapper
|
|
||||||
flex="col"
|
|
||||||
justify="top lg:justify-center"
|
|
||||||
slideFrom="right"
|
|
||||||
keepOpenOnClick
|
|
||||||
>
|
|
||||||
<div className="markdown max-w-prose">{docs}</div>
|
|
||||||
</ModalWrapper>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<DocsIcon />
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
const bottomLabelChildren = (
|
const bottomLabelChildren = (
|
||||||
<>
|
<>
|
||||||
|
@ -149,7 +121,6 @@ export const NumberInput = ({
|
||||||
current, // The current value
|
current, // The current value
|
||||||
original, // The original value
|
original, // The original value
|
||||||
placeholder, // The placeholder text
|
placeholder, // The placeholder text
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
id = '', // An id to tie the input to the label
|
id = '', // An id to tie the input to the label
|
||||||
labelBL = false, // Bottom-Left label
|
labelBL = false, // Bottom-Left label
|
||||||
labelBR = false, // Bottom-Right label
|
labelBR = false, // Bottom-Right label
|
||||||
|
@ -157,7 +128,7 @@ export const NumberInput = ({
|
||||||
min = 220,
|
min = 220,
|
||||||
step = 1,
|
step = 1,
|
||||||
}) => (
|
}) => (
|
||||||
<FormControl {...{ label, labelBL, labelBR, docs }} forId={id}>
|
<FormControl {...{ label, labelBL, labelBR }} forId={id}>
|
||||||
<input
|
<input
|
||||||
id={id}
|
id={id}
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -183,12 +154,11 @@ export const StringInput = ({
|
||||||
current, // The current value
|
current, // The current value
|
||||||
original, // The original value
|
original, // The original value
|
||||||
placeholder, // The placeholder text
|
placeholder, // The placeholder text
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
id = '', // An id to tie the input to the label
|
id = '', // An id to tie the input to the label
|
||||||
labelBL = false, // Bottom-Left label
|
labelBL = false, // Bottom-Left label
|
||||||
labelBR = false, // Bottom-Right label
|
labelBR = false, // Bottom-Right label
|
||||||
}) => (
|
}) => (
|
||||||
<FormControl {...{ label, labelBL, labelBR, docs }} forId={id}>
|
<FormControl {...{ label, labelBL, labelBR }} forId={id}>
|
||||||
<input
|
<input
|
||||||
id={id}
|
id={id}
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -220,7 +190,6 @@ export const MfaInput = ({
|
||||||
valid={(val) => val.length > 4}
|
valid={(val) => val.length > 4}
|
||||||
{...{ update, current, id }}
|
{...{ update, current, id }}
|
||||||
placeholder="MFA Code"
|
placeholder="MFA Code"
|
||||||
docs={false}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -234,7 +203,6 @@ export const PasswordInput = ({
|
||||||
valid, // Method that should return whether the value is valid or not
|
valid, // Method that should return whether the value is valid or not
|
||||||
current, // The current value
|
current, // The current value
|
||||||
placeholder = '¯\\_(ツ)_/¯', // The placeholder text
|
placeholder = '¯\\_(ツ)_/¯', // The placeholder text
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
id = '', // An id to tie the input to the label
|
id = '', // An id to tie the input to the label
|
||||||
onKeyDown = false, // Optionall capture certain keys (like enter)
|
onKeyDown = false, // Optionall capture certain keys (like enter)
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -245,7 +213,6 @@ export const PasswordInput = ({
|
||||||
return (
|
return (
|
||||||
<FormControl
|
<FormControl
|
||||||
label={label}
|
label={label}
|
||||||
docs={docs}
|
|
||||||
forId={id}
|
forId={id}
|
||||||
labelBR={
|
labelBR={
|
||||||
<button
|
<button
|
||||||
|
@ -281,12 +248,11 @@ export const EmailInput = ({
|
||||||
current, // The current value
|
current, // The current value
|
||||||
original, // The original value
|
original, // The original value
|
||||||
placeholder, // The placeholder text
|
placeholder, // The placeholder text
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
id = '', // An id to tie the input to the label
|
id = '', // An id to tie the input to the label
|
||||||
labelBL = false, // Bottom-Left label
|
labelBL = false, // Bottom-Left label
|
||||||
labelBR = false, // Bottom-Right label
|
labelBR = false, // Bottom-Right label
|
||||||
}) => (
|
}) => (
|
||||||
<FormControl {...{ label, docs, labelBL, labelBR }} forId={id}>
|
<FormControl {...{ label, labelBL, labelBR }} forId={id}>
|
||||||
<input
|
<input
|
||||||
id={id}
|
id={id}
|
||||||
type="email"
|
type="email"
|
||||||
|
@ -301,21 +267,20 @@ export const EmailInput = ({
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dropdown for designs
|
* Input for designs
|
||||||
*/
|
*/
|
||||||
export const DesignDropdown = ({
|
export const DesignInput = ({
|
||||||
label, // Label to use
|
label, // Label to use
|
||||||
update, // onChange handler
|
update, // onChange handler
|
||||||
current, // The current value
|
current, // The current value
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
firstOption = null, // Any first option to add in addition to designs
|
firstOption = null, // Any first option to add in addition to designs
|
||||||
id = '', // An id to tie the input to the label
|
id = '', // An id to tie the input to the label
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<FormControl label={label} docs={docs} forId={id}>
|
<FormControl label={label} forId={id}>
|
||||||
<select
|
<select
|
||||||
id={id}
|
id={id}
|
||||||
className="select select-bordered w-full"
|
className="daisy-select daisy-select-bordered w-full"
|
||||||
onChange={(evt) => update(evt.target.value)}
|
onChange={(evt) => update(evt.target.value)}
|
||||||
value={current}
|
value={current}
|
||||||
>
|
>
|
||||||
|
@ -338,7 +303,6 @@ export const ImageInput = ({
|
||||||
update, // The onChange handler
|
update, // The onChange handler
|
||||||
current, // The current value
|
current, // The current value
|
||||||
original, // The original value
|
original, // The original value
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
active = false, // Whether or not to upload images
|
active = false, // Whether or not to upload images
|
||||||
imgType = 'showcase', // The image type
|
imgType = 'showcase', // The image type
|
||||||
imgSubid, // The image sub-id
|
imgSubid, // The image sub-id
|
||||||
|
@ -383,7 +347,7 @@ export const ImageInput = ({
|
||||||
|
|
||||||
if (current)
|
if (current)
|
||||||
return (
|
return (
|
||||||
<FormControl label={label} docs={docs}>
|
<FormControl label={label}>
|
||||||
<div
|
<div
|
||||||
className="bg-base-100 w-full h-36 mb-2 mx-auto flex flex-col items-center text-center justify-center"
|
className="bg-base-100 w-full h-36 mb-2 mx-auto flex flex-col items-center text-center justify-center"
|
||||||
style={{
|
style={{
|
||||||
|
@ -396,7 +360,7 @@ export const ImageInput = ({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="btn btn-neutral btn-circle opacity-50 hover:opacity-100"
|
className="daisy-btn daisy-btn-neutral daisy-btn-circle opacity-50 hover:opacity-100"
|
||||||
onClick={() => update(original)}
|
onClick={() => update(original)}
|
||||||
>
|
>
|
||||||
<ResetIcon />
|
<ResetIcon />
|
||||||
|
@ -406,7 +370,7 @@ export const ImageInput = ({
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl label={label} docs={docs} forId={id}>
|
<FormControl label={label} forId={id}>
|
||||||
<div
|
<div
|
||||||
{...getRootProps()}
|
{...getRootProps()}
|
||||||
className={`
|
className={`
|
||||||
|
@ -417,7 +381,7 @@ export const ImageInput = ({
|
||||||
<input {...getInputProps()} />
|
<input {...getInputProps()} />
|
||||||
<p className="hidden lg:block p-0 m-0">Drag and drop and image here</p>
|
<p className="hidden lg:block p-0 m-0">Drag and drop and image here</p>
|
||||||
<p className="hidden lg:block p-0 my-2">or</p>
|
<p className="hidden lg:block p-0 my-2">or</p>
|
||||||
<button className={`btn btn-secondary btn-outline mt-4 px-8`}>
|
<button className={`daisy-btn daisy-btn-secondary daisy-btn-outline mt-4 px-8`}>
|
||||||
Select an image to use
|
Select an image to use
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -433,7 +397,7 @@ export const ImageInput = ({
|
||||||
/>
|
/>
|
||||||
{active && (
|
{active && (
|
||||||
<button
|
<button
|
||||||
className="btn btn-secondary ml-2 capitalize"
|
className="daisy-btn daisy-btn-secondary ml-2 capitalize"
|
||||||
disabled={!url || url.length < 1}
|
disabled={!url || url.length < 1}
|
||||||
onClick={() => upload(url, true)}
|
onClick={() => upload(url, true)}
|
||||||
>
|
>
|
||||||
|
@ -463,9 +427,8 @@ export const ListInput = ({
|
||||||
label, // The label
|
label, // The label
|
||||||
list, // The list of items to present { val, label, desc }
|
list, // The list of items to present { val, label, desc }
|
||||||
current, // The (value of the) current item
|
current, // The (value of the) current item
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
}) => (
|
}) => (
|
||||||
<FormControl label={label} docs={docs}>
|
<FormControl label={label}>
|
||||||
{list.map((item, i) => (
|
{list.map((item, i) => (
|
||||||
<ButtonFrame key={i} active={item.val === current} onClick={() => update(item.val)}>
|
<ButtonFrame key={i} active={item.val === current} onClick={() => update(item.val)}>
|
||||||
<div className="w-full flex flex-col gap-2">
|
<div className="w-full flex flex-col gap-2">
|
||||||
|
@ -489,15 +452,18 @@ export const MarkdownInput = ({
|
||||||
current, // The current value (markdown)
|
current, // The current value (markdown)
|
||||||
update, // The onChange handler
|
update, // The onChange handler
|
||||||
placeholder, // The placeholder content
|
placeholder, // The placeholder content
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
id = '', // An id to tie the input to the label
|
id = '', // An id to tie the input to the label
|
||||||
labelBL = false, // Bottom-Left label
|
labelBL = false, // Bottom-Left label
|
||||||
labelBR = false, // Bottom-Right label
|
labelBR = false, // Bottom-Right label
|
||||||
}) => (
|
}) => (
|
||||||
<FormControl {...{ label, labelBL, labelBR, docs }} forId={id}>
|
<FormControl
|
||||||
|
{...{ label, labelBR }}
|
||||||
|
forId={id}
|
||||||
|
labelBL={labelBL ? labelBL : 'This field supports markdown'}
|
||||||
|
>
|
||||||
<Tabs tabs={['edit', 'preview']}>
|
<Tabs tabs={['edit', 'preview']}>
|
||||||
<Tab key="edit">
|
<Tab key="edit">
|
||||||
<div className="flex flex-row items-center mt-4">
|
<div className="flex flex-row items-center">
|
||||||
<textarea
|
<textarea
|
||||||
id={id}
|
id={id}
|
||||||
rows="5"
|
rows="5"
|
||||||
|
@ -509,8 +475,8 @@ export const MarkdownInput = ({
|
||||||
</div>
|
</div>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab key="preview">
|
<Tab key="preview">
|
||||||
<div className="flex flex-row items-center mt-4">
|
<div className="flex flex-row items-center">
|
||||||
<Mdx md={current} />
|
<Markdown>{current}</Markdown>
|
||||||
</div>
|
</div>
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
@ -523,7 +489,6 @@ export const MeasieInput = ({
|
||||||
original, // The original value
|
original, // The original value
|
||||||
update, // The onChange handler
|
update, // The onChange handler
|
||||||
placeholder, // The placeholder content
|
placeholder, // The placeholder content
|
||||||
docs = false, // Docs to load, if any
|
|
||||||
id = '', // An id to tie the input to the label
|
id = '', // An id to tie the input to the label
|
||||||
}) => {
|
}) => {
|
||||||
const isDegree = isDegreeMeasurement(m)
|
const isDegree = isDegreeMeasurement(m)
|
||||||
|
@ -553,14 +518,14 @@ export const MeasieInput = ({
|
||||||
if (!m) return null
|
if (!m) return null
|
||||||
|
|
||||||
// Various visual indicators for validating the input
|
// Various visual indicators for validating the input
|
||||||
let inputClasses = 'input-secondary'
|
let inputClasses = 'daisy-input-secondary'
|
||||||
let bottomLeftLabel = null
|
let bottomLeftLabel = null
|
||||||
if (valid === true) {
|
if (valid === true) {
|
||||||
inputClasses = 'input-success'
|
inputClasses = 'daisy-input-success'
|
||||||
const val = `${validatedVal}${isDegree ? '°' : imperial ? '"' : 'cm'}`
|
const val = `${validatedVal}${isDegree ? '°' : imperial ? '"' : 'cm'}`
|
||||||
bottomLeftLabel = <span className="font-medium text-base text-success -mt-2 block">{val}</span>
|
bottomLeftLabel = <span className="font-medium text-base text-success -mt-2 block">{val}</span>
|
||||||
} else if (valid === false) {
|
} else if (valid === false) {
|
||||||
inputClasses = 'input-error'
|
inputClasses = 'daisy-input-error'
|
||||||
bottomLeftLabel = (
|
bottomLeftLabel = (
|
||||||
<span className="font-medium text-error text-base -mt-2 block">¯\_(ツ)_/¯</span>
|
<span className="font-medium text-error text-base -mt-2 block">¯\_(ツ)_/¯</span>
|
||||||
)
|
)
|
||||||
|
@ -574,12 +539,7 @@ export const MeasieInput = ({
|
||||||
* See: https://github.com/facebook/react/issues/16554
|
* See: https://github.com/facebook/react/issues/16554
|
||||||
*/
|
*/
|
||||||
return (
|
return (
|
||||||
<FormControl
|
<FormControl label={m + (isDegree ? ' (°)' : '')} forId={id} labelBL={bottomLeftLabel}>
|
||||||
label={t(m) + (isDegree ? ' (°)' : '')}
|
|
||||||
docs={docs}
|
|
||||||
forId={id}
|
|
||||||
labelBL={bottomLeftLabel}
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
id={id}
|
id={id}
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -588,7 +548,7 @@ export const MeasieInput = ({
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
value={localVal}
|
value={localVal}
|
||||||
onChange={(evt) => localUpdate(evt.target.value)}
|
onChange={(evt) => localUpdate(evt.target.value)}
|
||||||
className={`input w-full input-bordered ${inputClasses}`}
|
className={`daisy-input w-full daisy-input-bordered ${inputClasses}`}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)
|
)
|
||||||
|
@ -628,7 +588,7 @@ export const FileInput = ({
|
||||||
<FormControl label={label} isValid={valid(current)}>
|
<FormControl label={label} isValid={valid(current)}>
|
||||||
<div className="bg-base-100 w-full h-36 mb-2 mx-auto flex flex-col items-center text-center justify-center">
|
<div className="bg-base-100 w-full h-36 mb-2 mx-auto flex flex-col items-center text-center justify-center">
|
||||||
<button
|
<button
|
||||||
className="btn btn-neutral btn-circle opacity-50 hover:opacity-100"
|
className="daisy-btn daisy-btn-neutral daisy-btn-circle opacity-50 hover:opacity-100"
|
||||||
onClick={() => update(original)}
|
onClick={() => update(original)}
|
||||||
>
|
>
|
||||||
<ResetIcon />
|
<ResetIcon />
|
||||||
|
@ -651,7 +611,9 @@ export const FileInput = ({
|
||||||
>
|
>
|
||||||
<input {...getInputProps()} />
|
<input {...getInputProps()} />
|
||||||
<p className="hidden lg:block p-0 m-0">Drag and drop your file here</p>
|
<p className="hidden lg:block p-0 m-0">Drag and drop your file here</p>
|
||||||
<button className={`btn btn-secondary btn-outline mt-4 px-8`}>Browse...</button>
|
<button className={`daisy-btn daisy-btn-secondary daisy-btn-outline mt-4 px-8`}>
|
||||||
|
Browse...
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,5 +5,7 @@ import hljs from 'highlight.js/lib/common'
|
||||||
export const Json = (props) => {
|
export const Json = (props) => {
|
||||||
const code = props.js ? JSON.stringify(props.js, null, 2) : props.children
|
const code = props.js ? JSON.stringify(props.js, null, 2) : props.children
|
||||||
|
|
||||||
return <Highlight language="json" raw={hljs.highlight(code, { language: 'json' }).value} />
|
return (
|
||||||
|
<Highlight language="json" raw={hljs.highlight(code, { language: 'json' }).value} copy={code} />
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ export const ModalWrapper = ({
|
||||||
flex = 'row',
|
flex = 'row',
|
||||||
justify = 'center',
|
justify = 'center',
|
||||||
items = 'center',
|
items = 'center',
|
||||||
bg = 'base-100 lg:bg-base-300',
|
bg = 'neutral lg:neutral',
|
||||||
bgOpacity = '100 lg:bg-opacity-95',
|
bgOpacity = '100 lg:bg-opacity-70',
|
||||||
bare = false,
|
bare = false,
|
||||||
keepOpenOnClick = false,
|
keepOpenOnClick = false,
|
||||||
slideFrom = 'left',
|
slideFrom = 'left',
|
||||||
|
@ -68,9 +68,10 @@ export const ModalWrapper = ({
|
||||||
<div
|
<div
|
||||||
className={`fixed top-0 left-0 m-0 p-0 shadow w-full h-screen
|
className={`fixed top-0 left-0 m-0 p-0 shadow w-full h-screen
|
||||||
transform-all duration-150 ${animation}
|
transform-all duration-150 ${animation}
|
||||||
bg-${bg} bg-opacity-${bgOpacity} z-40 hover:cursor-pointer
|
bg-${bg} bg-opacity-${bgOpacity} hover:cursor-pointer
|
||||||
flex flex-${flex} justify-${justify} items-${items} lg:p-12`}
|
flex flex-${flex} justify-${justify} items-${items} lg:p-12 backdrop-blur-md`}
|
||||||
onClick={close}
|
onClick={close}
|
||||||
|
style={{ zIndex: 250 }}
|
||||||
>
|
>
|
||||||
{bare ? (
|
{bare ? (
|
||||||
children
|
children
|
||||||
|
|
|
@ -1,8 +1,104 @@
|
||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
import { mergeProps } from './utils.mjs'
|
import { CloseIcon } from '@freesewing/react/components/Icon'
|
||||||
import { Popout as SwizzledPopout } from './editor/swizzle/components/popout.mjs'
|
|
||||||
import { CloseIcon } from './editor/swizzle/components/icons.mjs'
|
|
||||||
|
|
||||||
const t = (id) => id
|
const colors = {
|
||||||
|
comment: 'secondary',
|
||||||
|
error: 'error',
|
||||||
|
fixme: 'warning',
|
||||||
|
link: 'secondary',
|
||||||
|
none: '',
|
||||||
|
note: 'primary',
|
||||||
|
related: 'info',
|
||||||
|
tip: 'accent',
|
||||||
|
tldr: 'info',
|
||||||
|
warning: 'error',
|
||||||
|
}
|
||||||
|
|
||||||
export const Popout = (props) => <SwizzledPopout {...mergeProps(props, { CloseIcon }, { t })} />
|
/**
|
||||||
|
* This popout component is a way to make some content stand out
|
||||||
|
*
|
||||||
|
* @param {object} props - All React props
|
||||||
|
* @param {object} props.comment - Set this to make it a comment popout
|
||||||
|
* @param {object} props.error - Set this to make it a error popout
|
||||||
|
* @param {object} props.fixme - Set this to make it a fixme popout
|
||||||
|
* @param {object} props.link - Set this to make it a link popout
|
||||||
|
* @param {object} props.note - Set this to make it a note popout
|
||||||
|
* @param {object} props.related - Set this to make it a related popout
|
||||||
|
* @param {object} props.tip - Set this to make it a tip popout
|
||||||
|
* @param {object} props.tldr - Set this to make it a tldr popout
|
||||||
|
* @param {object} props.warning - Set this to make it a warning popout
|
||||||
|
* @param {string} props.title - The popout title
|
||||||
|
* @param {string} noP - Do not wrap the content in a p tag
|
||||||
|
*/
|
||||||
|
export const Popout = (props) => {
|
||||||
|
// Make this hideable/dismissable
|
||||||
|
const [hide, setHide] = useState(false)
|
||||||
|
if (hide) return null
|
||||||
|
|
||||||
|
let type = 'none'
|
||||||
|
for (const c in colors) {
|
||||||
|
if (props[c]) type = c
|
||||||
|
}
|
||||||
|
const color = colors[type]
|
||||||
|
const { className = '' } = props
|
||||||
|
|
||||||
|
return props.compact ? (
|
||||||
|
<div
|
||||||
|
className={`relative ${
|
||||||
|
props.dense ? 'my-1' : 'my-8'
|
||||||
|
} bg-${color} bg-opacity-5 -ml-4 -mr-4 sm:ml-0 sm:mr-0 ${className}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`
|
||||||
|
border-y-4 sm:border-0 sm:border-l-4 px-4
|
||||||
|
shadow text-base border-${color}
|
||||||
|
flex flex-row items-center
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<div className={`font-bold uppercase text-${color}`}>
|
||||||
|
{props.title || (
|
||||||
|
<>
|
||||||
|
<span>{type.toUpperCase()}</span>
|
||||||
|
<span className="px-3">|</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="popout-content">{props.noP ? props.children : <p>{props.children}</p>}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className={`relative my-8 bg-${color} bg-opacity-5 -ml-4 -mr-4 sm:ml-0 sm:mr-0 ${className}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`
|
||||||
|
border-y-4 sm:border-0 sm:border-l-4 px-6 sm:px-8 py-4 sm:py-2
|
||||||
|
shadow text-base border-${color}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<div className={`font-bold flex flex-row gap-1 items-end justify-between`}>
|
||||||
|
<div>
|
||||||
|
<span className={`font-bold uppercase text-${color}`}>
|
||||||
|
{type === 'tldr' ? 'TL;DR' : type.toUpperCase()}
|
||||||
|
</span>
|
||||||
|
<span className={`font-normal text-base text-${color}`}>
|
||||||
|
{type === 'comment' && (
|
||||||
|
<>
|
||||||
|
{' '}
|
||||||
|
by <b>{props.by}</b>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{props.hideable && (
|
||||||
|
<button onClick={() => setHide(true)} className="hover:text-secondary" title="Close">
|
||||||
|
<CloseIcon />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="py-1 first:mt-0 popout-content">{props.children}</div>
|
||||||
|
{type === 'comment' && <div className={`font-bold italic text-${color}`}>{props.by}</div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -31,16 +31,17 @@ export const Tabs = ({ tabs = '', active = 0, children, withModal = false }) =>
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="my-4">
|
<div className="">
|
||||||
<div className="tabs">
|
<div className="daisy-tabs daisy-tabs-bordered" role="tablist">
|
||||||
{tablist.map((title, tabId) => {
|
{tablist.map((title, tabId) => {
|
||||||
const btnClasses = `text-lg font-bold capitalize tab h-auto tab-bordered grow py-2 ${
|
const btnClasses = `text-lg font-bold capitalize daisy-tab h-auto daisy-tabs-bordered grow py-1 ${
|
||||||
activeTab === tabId ? 'tab-active' : ''
|
activeTab === tabId ? 'daisy-tab-active' : ''
|
||||||
}`
|
}`
|
||||||
|
|
||||||
return withModal && activeTab === tabId ? (
|
return withModal && activeTab === tabId ? (
|
||||||
<button
|
<button
|
||||||
key={tabId}
|
key={tabId}
|
||||||
|
role="tab"
|
||||||
className={btnClasses}
|
className={btnClasses}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setModal(
|
setModal(
|
||||||
|
|
|
@ -10,6 +10,11 @@ export const Yaml = (props) => {
|
||||||
else code = props.children
|
else code = props.children
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Highlight {...props} language="yaml" raw={hljs.highlight(code, { language: 'yaml' }).value} />
|
<Highlight
|
||||||
|
{...props}
|
||||||
|
language="yaml"
|
||||||
|
raw={hljs.highlight(code, { language: 'yaml' }).value}
|
||||||
|
copy={code}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,10 @@ const LoadingStatus = ({ loadingStatus }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed bottom-14 md:top-28 left-0 w-full z-50 md:px-4 md:mx-auto">
|
<div
|
||||||
|
className="fixed bottom-14 md:top-28 left-0 w-full z-50 md:px-4 md:mx-auto"
|
||||||
|
style={{ zIndex: 500 }}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className={`w-full md:max-w-2xl m-auto bg-${color} flex flex-row items-center gap-4 p-4 px-4 ${fade}
|
className={`w-full md:max-w-2xl m-auto bg-${color} flex flex-row items-center gap-4 p-4 px-4 ${fade}
|
||||||
transition-opacity delay-[${timeout * 1000 - 400}ms] duration-300
|
transition-opacity delay-[${timeout * 1000 - 400}ms] duration-300
|
||||||
|
|
|
@ -3,4 +3,12 @@ title: Create a new measurement set
|
||||||
sidebar_position: 2
|
sidebar_position: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
FIXME
|
import { DocusaurusDoc } from '@freesewing/react/components/Docusaurus'
|
||||||
|
import { RoleBlock } from '@freesewing/react/components/Role'
|
||||||
|
import { NewSet } from '@freesewing/react/components/Account'
|
||||||
|
|
||||||
|
<DocusaurusDoc>
|
||||||
|
<RoleBlock user>
|
||||||
|
<NewSet />
|
||||||
|
</RoleBlock>
|
||||||
|
</DocusaurusDoc>
|
||||||
|
|
161
sites/org/src/css/code.css
Normal file
161
sites/org/src/css/code.css
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/* __SDEFILE__ - This file is a dependency for the stand-alone environment */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS file for highlightjs, with support for (DaisyUI) themes
|
||||||
|
*
|
||||||
|
* Do not edit this file, edit the theme configuration instead
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The div wrapping the code block */
|
||||||
|
div.hljs {
|
||||||
|
background: var(--code-background-color);
|
||||||
|
border-color: var(--code-border-color);
|
||||||
|
border-width: var(--code-border-width);
|
||||||
|
border-style: var(--code-border-style);
|
||||||
|
padding: 0;
|
||||||
|
color: var(--code-color);
|
||||||
|
border-radius: var(--code-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The code block inside the wrapping div */
|
||||||
|
div.hljs > pre {
|
||||||
|
background: var(--code-bg);
|
||||||
|
color: var(--code-color);
|
||||||
|
padding: var(--code-inner-padding);
|
||||||
|
font-family: var(--code-font-family);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix for the tailwind typography plugin (aka prose) that
|
||||||
|
* adds padding to code that makes it look like there's a
|
||||||
|
* extra space on the first line
|
||||||
|
*/
|
||||||
|
div.hljs > pre > code {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Higlight lines within a highlighted code block
|
||||||
|
*/
|
||||||
|
div.hljs > pre > code section {
|
||||||
|
margin: 0 -1rem;
|
||||||
|
padding: 0 1rem 0 calc(1rem - 4px);
|
||||||
|
border-left: 0.35rem solid transparent;
|
||||||
|
border-color: rgb(130, 203, 21);
|
||||||
|
background-color: var(--code-background-highlight-color);
|
||||||
|
}
|
||||||
|
div.hljs > pre > code section > div.code-section-inner {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.25rem 0.25rem 0.25rem 0;
|
||||||
|
background-color: var(--code-background-highlight-color);
|
||||||
|
}
|
||||||
|
div.hljs > pre > code section.strikeout-lines {
|
||||||
|
border-color: rgb(255, 75, 57);
|
||||||
|
}
|
||||||
|
div.hljs > pre > code section > span.code-line-break:last-child {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: keyword
|
||||||
|
*/
|
||||||
|
.hljs-doctag,
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-meta .hljs-keyword,
|
||||||
|
.hljs-template-tag,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-variable.language_ {
|
||||||
|
color: var(--code-color-keyword);
|
||||||
|
font-weight: var(--code-font-weight-keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: entity
|
||||||
|
*/
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-title.class_,
|
||||||
|
.hljs-title.class_.inherited__,
|
||||||
|
.hljs-title.function_ {
|
||||||
|
color: var(--code-color-entity);
|
||||||
|
font-weight: var(--code-font-weight-entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: constant
|
||||||
|
*/
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-meta,
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-operator,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-selector-id {
|
||||||
|
color: var(--code-color-constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: string
|
||||||
|
*/
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-meta .hljs-string {
|
||||||
|
color: var(--code-color-string);
|
||||||
|
font-style: var(--code-font-style-string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: variable
|
||||||
|
*/
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-symbol {
|
||||||
|
color: var(--code-color-variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: comment
|
||||||
|
*/
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-code,
|
||||||
|
.hljs-formula {
|
||||||
|
color: var(--code-color-comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: tag
|
||||||
|
*/
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-quote,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-selector-pseudo {
|
||||||
|
color: var(--code-color-tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: property
|
||||||
|
*/
|
||||||
|
.hljs-property {
|
||||||
|
color: var(--code-color-property);
|
||||||
|
font-weight: var(--code-font-weight-property);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSS for highlighted code: other
|
||||||
|
*/
|
||||||
|
.hljs-addition,
|
||||||
|
.hljs-bullet,
|
||||||
|
.hljs-char.escape_,
|
||||||
|
.hljs-deletion,
|
||||||
|
.hljs-emphasis,
|
||||||
|
.hljs-link,
|
||||||
|
.hljs-params,
|
||||||
|
.hljs-punctuation,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-strong,
|
||||||
|
.hljs-subst,
|
||||||
|
.hljs-tag {
|
||||||
|
/* Currently not using these */
|
||||||
|
}
|
|
@ -12,6 +12,11 @@
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add CSS for code
|
||||||
|
*/
|
||||||
|
@import './code.css';
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
/* Applied styles for common HTML tags */
|
/* Applied styles for common HTML tags */
|
||||||
h1 {
|
h1 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue