@lt-three/love3 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +86 -2
- package/dist/native/analytics/animation.d.ts +4 -0
- package/dist/native/analytics/animation.js +6 -0
- package/dist/native/analytics/chart.types.d.ts +25 -0
- package/dist/native/analytics/chart.types.js +0 -0
- package/dist/native/analytics/line-chart.d.ts +4 -0
- package/dist/native/analytics/line-chart.ios.d.ts +4 -0
- package/dist/native/analytics/line-chart.ios.js +24 -0
- package/dist/native/analytics/line-chart.js +33 -0
- package/dist/native/analytics/metric-card.d.ts +10 -0
- package/dist/native/analytics/metric-card.js +29 -0
- package/dist/native/analytics/multi-line-chart.d.ts +17 -0
- package/dist/native/analytics/multi-line-chart.js +215 -0
- package/dist/native/analytics/pie-chart.d.ts +15 -0
- package/dist/native/analytics/pie-chart.ios.d.ts +4 -0
- package/dist/native/analytics/pie-chart.ios.js +24 -0
- package/dist/native/analytics/pie-chart.js +92 -0
- package/dist/native/analytics/single-number.d.ts +19 -0
- package/dist/native/analytics/single-number.js +101 -0
- package/dist/native/atom/avatar.d.ts +21 -0
- package/dist/native/atom/avatar.js +46 -0
- package/dist/native/atom/badge.d.ts +28 -0
- package/dist/native/atom/badge.js +51 -0
- package/dist/native/atom/button.d.ts +46 -0
- package/dist/native/atom/button.js +109 -0
- package/dist/native/atom/checkbox.d.ts +21 -0
- package/dist/native/atom/checkbox.js +47 -0
- package/dist/native/atom/colored-value.d.ts +12 -0
- package/dist/native/atom/colored-value.js +24 -0
- package/dist/native/atom/image.d.ts +21 -0
- package/dist/native/atom/image.js +72 -0
- package/dist/native/atom/label.d.ts +18 -0
- package/dist/native/atom/label.js +33 -0
- package/dist/native/atom/link.d.ts +18 -0
- package/dist/native/atom/link.js +25 -0
- package/dist/native/atom/readout.d.ts +22 -0
- package/dist/native/atom/readout.js +39 -0
- package/dist/native/atom/search-input.d.ts +12 -0
- package/dist/native/atom/search-input.js +36 -0
- package/dist/native/atom/select.d.ts +54 -0
- package/dist/native/atom/select.js +200 -0
- package/dist/native/atom/separator.d.ts +13 -0
- package/dist/native/atom/separator.js +17 -0
- package/dist/native/atom/skeleton.d.ts +12 -0
- package/dist/native/atom/skeleton.js +39 -0
- package/dist/native/atom/slider.d.ts +32 -0
- package/dist/native/atom/slider.js +75 -0
- package/dist/native/atom/spinner.d.ts +15 -0
- package/dist/native/atom/spinner.js +25 -0
- package/dist/native/atom/switch.d.ts +18 -0
- package/dist/native/atom/switch.js +52 -0
- package/dist/native/atom/symbol.d.ts +16 -0
- package/dist/native/atom/symbol.js +38 -0
- package/dist/native/atom/symbol.types.d.ts +25 -0
- package/dist/native/atom/symbol.types.js +49 -0
- package/dist/native/atom/text-field.d.ts +49 -0
- package/dist/native/atom/text-field.js +56 -0
- package/dist/native/atom/text.d.ts +2 -0
- package/dist/native/atom/text.js +3 -0
- package/dist/native/atom/theme-toggle.d.ts +21 -0
- package/dist/native/atom/theme-toggle.js +36 -0
- package/dist/native/atom/timezone-select.d.ts +16 -0
- package/dist/native/atom/timezone-select.js +28 -0
- package/dist/native/atom/typography.d.ts +13 -0
- package/dist/native/atom/typography.js +28 -0
- package/dist/native/base/button.d.ts +61 -0
- package/dist/native/base/button.js +92 -0
- package/dist/native/base/form.d.ts +72 -0
- package/dist/native/base/form.js +113 -0
- package/dist/native/base/glass-card.d.ts +15 -0
- package/dist/native/base/glass-card.js +38 -0
- package/dist/native/base/input.d.ts +29 -0
- package/dist/native/base/input.js +27 -0
- package/dist/native/base/sheet.d.ts +71 -0
- package/dist/native/base/sheet.js +187 -0
- package/dist/native/base/text.d.ts +14 -0
- package/dist/native/base/text.js +53 -0
- package/dist/native/form/checkbox.d.ts +13 -0
- package/dist/native/form/checkbox.js +55 -0
- package/dist/native/form/date-picker.d.ts +23 -0
- package/dist/native/form/date-picker.js +119 -0
- package/dist/native/form/form.d.ts +23 -0
- package/dist/native/form/form.js +45 -0
- package/dist/native/form/radio-group.d.ts +23 -0
- package/dist/native/form/radio-group.js +88 -0
- package/dist/native/form/select.d.ts +13 -0
- package/dist/native/form/select.js +45 -0
- package/dist/native/form/slider.d.ts +14 -0
- package/dist/native/form/slider.js +42 -0
- package/dist/native/form/switch.d.ts +9 -0
- package/dist/native/form/switch.js +59 -0
- package/dist/native/form/text-area.d.ts +11 -0
- package/dist/native/form/text-area.js +50 -0
- package/dist/native/form/text-input.d.ts +18 -0
- package/dist/native/form/text-input.js +90 -0
- package/dist/native/index.d.ts +1 -0
- package/dist/native/index.js +0 -0
- package/dist/native/layout/accordion.d.ts +25 -0
- package/dist/native/layout/accordion.js +54 -0
- package/dist/native/layout/card.d.ts +47 -0
- package/dist/native/layout/card.js +57 -0
- package/dist/native/layout/description.d.ts +16 -0
- package/dist/native/layout/description.js +32 -0
- package/dist/native/layout/error.d.ts +21 -0
- package/dist/native/layout/error.js +44 -0
- package/dist/native/layout/information.d.ts +25 -0
- package/dist/native/layout/information.js +35 -0
- package/dist/native/layout/locked.d.ts +38 -0
- package/dist/native/layout/locked.js +94 -0
- package/dist/native/layout/modal.d.ts +25 -0
- package/dist/native/layout/modal.js +93 -0
- package/dist/native/layout/not-found.d.ts +17 -0
- package/dist/native/layout/not-found.js +30 -0
- package/dist/native/layout/page-frame.d.ts +23 -0
- package/dist/native/layout/page-frame.js +46 -0
- package/dist/native/layout/panel.d.ts +18 -0
- package/dist/native/layout/panel.js +23 -0
- package/dist/native/layout/reorderable-list.d.ts +42 -0
- package/dist/native/layout/reorderable-list.js +52 -0
- package/dist/native/layout/sheet.d.ts +30 -0
- package/dist/native/layout/sheet.js +46 -0
- package/dist/native/layout/simple-dialog.d.ts +16 -0
- package/dist/native/layout/simple-dialog.js +20 -0
- package/dist/native/layout/simple-table.d.ts +50 -0
- package/dist/native/layout/simple-table.js +75 -0
- package/dist/native/layout/tab-bar.d.ts +33 -0
- package/dist/native/layout/tab-bar.js +48 -0
- package/dist/native/layout/tabs.d.ts +28 -0
- package/dist/native/layout/tabs.js +54 -0
- package/dist/native/layout/tuning-panel.d.ts +24 -0
- package/dist/native/layout/tuning-panel.js +246 -0
- package/dist/native/lib/autocomplete.d.ts +7 -0
- package/dist/native/lib/autocomplete.js +34 -0
- package/dist/native/lib/breakpoints.d.ts +14 -0
- package/dist/native/lib/breakpoints.js +17 -0
- package/dist/native/lib/chart-palette.d.ts +8 -0
- package/dist/native/lib/chart-palette.js +20 -0
- package/dist/native/lib/confirm.d.ts +49 -0
- package/dist/native/lib/confirm.js +70 -0
- package/dist/native/lib/control.d.ts +24 -0
- package/dist/native/lib/control.js +0 -0
- package/dist/native/lib/external-store.d.ts +17 -0
- package/dist/native/lib/external-store.js +30 -0
- package/dist/native/lib/keyboard.d.ts +15 -0
- package/dist/native/lib/keyboard.js +24 -0
- package/dist/native/lib/labels.d.ts +15 -0
- package/dist/native/lib/labels.js +17 -0
- package/dist/native/lib/loading.d.ts +10 -0
- package/dist/native/lib/loading.js +15 -0
- package/dist/native/lib/network.d.ts +12 -0
- package/dist/native/lib/network.js +21 -0
- package/dist/native/lib/scheme.d.ts +18 -0
- package/dist/native/lib/scheme.js +22 -0
- package/dist/native/lib/snackbar.d.ts +46 -0
- package/dist/native/lib/snackbar.js +60 -0
- package/dist/native/lib/theme.d.ts +34 -0
- package/dist/native/lib/theme.js +53 -0
- package/dist/native/lib/timezone.d.ts +26 -0
- package/dist/native/lib/timezone.js +95 -0
- package/dist/native/lib/token-color.d.ts +5 -0
- package/dist/native/lib/token-color.js +13 -0
- package/dist/native/lib/token-color.web.d.ts +4 -0
- package/dist/native/lib/token-color.web.js +7 -0
- package/dist/native/lib/tuning-context.d.ts +9 -0
- package/dist/native/lib/tuning-context.js +7 -0
- package/dist/native/lib/tuning.d.ts +24 -0
- package/dist/native/lib/tuning.js +42 -0
- package/dist/native/lib/typography.d.ts +10 -0
- package/dist/native/lib/typography.js +11 -0
- package/dist/native/lib/utils.d.ts +11 -0
- package/dist/native/lib/utils.js +21 -0
- package/dist/native/once/confirm.d.ts +7 -0
- package/dist/native/once/confirm.js +60 -0
- package/dist/native/once/error-boundary.d.ts +28 -0
- package/dist/native/once/error-boundary.js +55 -0
- package/dist/native/once/loading-lock.d.ts +8 -0
- package/dist/native/once/loading-lock.js +28 -0
- package/dist/native/once/offline-banner.d.ts +15 -0
- package/dist/native/once/offline-banner.js +35 -0
- package/dist/native/once/snackbar.d.ts +17 -0
- package/dist/native/once/snackbar.js +106 -0
- package/dist/native/styles.css +46 -0
- package/dist/shared/analytics.d.ts +71 -0
- package/dist/shared/analytics.js +0 -0
- package/dist/shared/button.d.ts +7 -0
- package/dist/shared/button.js +23 -0
- package/dist/shared/form.d.ts +45 -0
- package/dist/shared/form.js +46 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/tokens/contrast-pairs.d.ts +30 -0
- package/dist/tokens/contrast-pairs.js +404 -0
- package/dist/tokens/index.d.ts +6 -0
- package/dist/tokens/index.js +10 -0
- package/dist/tokens/styles.gen.css +250 -0
- package/dist/tokens/tokens.gen.d.ts +141 -0
- package/dist/tokens/tokens.gen.js +206 -0
- package/dist/tuning/catalog.d.ts +27 -0
- package/dist/tuning/catalog.gen.d.ts +4 -0
- package/dist/tuning/catalog.gen.js +397 -0
- package/dist/tuning/catalog.js +128 -0
- package/dist/tuning/color.d.ts +20 -0
- package/dist/tuning/color.js +80 -0
- package/dist/tuning/css.d.ts +35 -0
- package/dist/tuning/css.js +147 -0
- package/dist/tuning/index.d.ts +8 -0
- package/dist/tuning/index.js +9 -0
- package/dist/tuning/model.d.ts +33 -0
- package/dist/tuning/model.js +154 -0
- package/dist/tuning/native.d.ts +35 -0
- package/dist/tuning/native.js +80 -0
- package/dist/tuning/schema.d.ts +69 -0
- package/dist/tuning/schema.js +247 -0
- package/dist/tuning/types.d.ts +75 -0
- package/dist/tuning/types.js +39 -0
- package/dist/web/analytics/line-chart.d.ts +20 -0
- package/dist/web/analytics/line-chart.js +28 -0
- package/dist/web/analytics/metric-card.d.ts +18 -0
- package/dist/web/analytics/metric-card.js +40 -0
- package/dist/web/analytics/multi-line-chart.d.ts +39 -0
- package/dist/web/analytics/multi-line-chart.js +345 -0
- package/dist/web/atom/avatar.d.ts +11 -0
- package/dist/web/atom/avatar.js +24 -0
- package/dist/web/atom/badge.d.ts +2 -0
- package/dist/web/atom/badge.js +3 -0
- package/dist/web/atom/button.d.ts +23 -0
- package/dist/web/atom/button.js +35 -0
- package/dist/web/atom/checkbox.d.ts +19 -0
- package/dist/web/atom/checkbox.js +33 -0
- package/dist/web/atom/colored-value.d.ts +13 -0
- package/dist/web/atom/colored-value.js +24 -0
- package/dist/web/atom/help.d.ts +10 -0
- package/dist/web/atom/help.js +18 -0
- package/dist/web/atom/label.d.ts +2 -0
- package/dist/web/atom/label.js +3 -0
- package/dist/web/atom/segmented-control.d.ts +40 -0
- package/dist/web/atom/segmented-control.js +43 -0
- package/dist/web/atom/select.d.ts +43 -0
- package/dist/web/atom/select.js +93 -0
- package/dist/web/atom/separator.d.ts +2 -0
- package/dist/web/atom/separator.js +3 -0
- package/dist/web/atom/skeleton.d.ts +2 -0
- package/dist/web/atom/skeleton.js +3 -0
- package/dist/web/atom/slider.d.ts +33 -0
- package/dist/web/atom/slider.js +70 -0
- package/dist/web/atom/spinner.d.ts +8 -0
- package/dist/web/atom/spinner.js +14 -0
- package/dist/web/atom/switch.d.ts +11 -0
- package/dist/web/atom/switch.js +10 -0
- package/dist/web/atom/text-area.d.ts +22 -0
- package/dist/web/atom/text-area.js +26 -0
- package/dist/web/atom/text-field.d.ts +17 -0
- package/dist/web/atom/text-field.js +21 -0
- package/dist/web/atom/toggle-chip.d.ts +22 -0
- package/dist/web/atom/toggle-chip.js +28 -0
- package/dist/web/atom/tooltip.d.ts +23 -0
- package/dist/web/atom/tooltip.js +26 -0
- package/dist/web/atom/typography.d.ts +6 -0
- package/dist/web/atom/typography.js +23 -0
- package/dist/web/base/accordion.d.ts +9 -0
- package/dist/web/base/accordion.js +44 -0
- package/dist/web/base/alert.d.ts +11 -0
- package/dist/web/base/alert.js +37 -0
- package/dist/web/base/avatar.d.ts +8 -0
- package/dist/web/base/avatar.js +29 -0
- package/dist/web/base/badge.d.ts +12 -0
- package/dist/web/base/badge.js +26 -0
- package/dist/web/base/breadcrumb.d.ts +16 -0
- package/dist/web/base/breadcrumb.js +72 -0
- package/dist/web/base/button.d.ts +12 -0
- package/dist/web/base/button.js +47 -0
- package/dist/web/base/card.d.ts +19 -0
- package/dist/web/base/card.js +74 -0
- package/dist/web/base/checkbox.d.ts +6 -0
- package/dist/web/base/checkbox.js +21 -0
- package/dist/web/base/dialog.d.ts +20 -0
- package/dist/web/base/dialog.js +92 -0
- package/dist/web/base/dropdown-menu.d.ts +29 -0
- package/dist/web/base/dropdown-menu.js +125 -0
- package/dist/web/base/field.d.ts +27 -0
- package/dist/web/base/field.js +118 -0
- package/dist/web/base/form.d.ts +38 -0
- package/dist/web/base/form.js +110 -0
- package/dist/web/base/input.d.ts +9 -0
- package/dist/web/base/input.js +23 -0
- package/dist/web/base/label.d.ts +6 -0
- package/dist/web/base/label.js +15 -0
- package/dist/web/base/pagination.d.ts +34 -0
- package/dist/web/base/pagination.js +90 -0
- package/dist/web/base/popover.d.ts +11 -0
- package/dist/web/base/popover.js +37 -0
- package/dist/web/base/radio-group.d.ts +7 -0
- package/dist/web/base/radio-group.js +27 -0
- package/dist/web/base/scroll-area.d.ts +10 -0
- package/dist/web/base/scroll-area.js +41 -0
- package/dist/web/base/select.d.ts +17 -0
- package/dist/web/base/select.js +96 -0
- package/dist/web/base/separator.d.ts +6 -0
- package/dist/web/base/separator.js +17 -0
- package/dist/web/base/sheet.d.ts +19 -0
- package/dist/web/base/sheet.js +88 -0
- package/dist/web/base/skeleton.d.ts +5 -0
- package/dist/web/base/skeleton.js +14 -0
- package/dist/web/base/slider.d.ts +9 -0
- package/dist/web/base/slider.js +39 -0
- package/dist/web/base/sonner.d.ts +9 -0
- package/dist/web/base/sonner.js +25 -0
- package/dist/web/base/spinner.d.ts +5 -0
- package/dist/web/base/spinner.js +17 -0
- package/dist/web/base/switch.d.ts +6 -0
- package/dist/web/base/switch.js +19 -0
- package/dist/web/base/table.d.ts +14 -0
- package/dist/web/base/table.js +68 -0
- package/dist/web/base/tabs.d.ts +9 -0
- package/dist/web/base/tabs.js +36 -0
- package/dist/web/base/textarea.d.ts +9 -0
- package/dist/web/base/textarea.js +23 -0
- package/dist/web/base/tooltip.d.ts +9 -0
- package/dist/web/base/tooltip.js +36 -0
- package/dist/web/form/checkbox.d.ts +35 -0
- package/dist/web/form/checkbox.js +91 -0
- package/dist/web/form/radio-group.d.ts +24 -0
- package/dist/web/form/radio-group.js +75 -0
- package/dist/web/form/select.d.ts +16 -0
- package/dist/web/form/select.js +44 -0
- package/dist/web/form/slider.d.ts +19 -0
- package/dist/web/form/slider.js +51 -0
- package/dist/web/form/switch.d.ts +11 -0
- package/dist/web/form/switch.js +50 -0
- package/dist/web/form/text-area.d.ts +10 -0
- package/dist/web/form/text-area.js +31 -0
- package/dist/web/form/text-input.d.ts +10 -0
- package/dist/web/form/text-input.js +42 -0
- package/dist/web/index.d.ts +1 -0
- package/dist/web/index.js +0 -0
- package/dist/web/layout/accordion.d.ts +26 -0
- package/dist/web/layout/accordion.js +29 -0
- package/dist/web/layout/alert-modal.d.ts +41 -0
- package/dist/web/layout/alert-modal.js +71 -0
- package/dist/web/layout/card.d.ts +17 -0
- package/dist/web/layout/card.js +35 -0
- package/dist/web/layout/description.d.ts +12 -0
- package/dist/web/layout/description.js +20 -0
- package/dist/web/layout/information.d.ts +36 -0
- package/dist/web/layout/information.js +53 -0
- package/dist/web/layout/modal.d.ts +16 -0
- package/dist/web/layout/modal.js +37 -0
- package/dist/web/layout/page-frame.d.ts +37 -0
- package/dist/web/layout/page-frame.js +79 -0
- package/dist/web/layout/scroll-area.d.ts +10 -0
- package/dist/web/layout/scroll-area.js +13 -0
- package/dist/web/layout/sheet.d.ts +32 -0
- package/dist/web/layout/sheet.js +68 -0
- package/dist/web/layout/simple-dialog.d.ts +11 -0
- package/dist/web/layout/simple-dialog.js +24 -0
- package/dist/web/layout/simple-table.d.ts +49 -0
- package/dist/web/layout/simple-table.js +58 -0
- package/dist/web/layout/tabs.d.ts +26 -0
- package/dist/web/layout/tabs.js +42 -0
- package/dist/web/layout/titled-modal.d.ts +33 -0
- package/dist/web/layout/titled-modal.js +59 -0
- package/dist/web/lib/css-vars.d.ts +14 -0
- package/dist/web/lib/css-vars.js +18 -0
- package/dist/web/lib/dialog.d.ts +13 -0
- package/dist/web/lib/dialog.js +0 -0
- package/dist/web/lib/form.d.ts +2 -0
- package/dist/web/lib/form.js +3 -0
- package/dist/web/lib/labels.d.ts +27 -0
- package/dist/web/lib/labels.js +29 -0
- package/dist/web/lib/modal-open-focus.d.ts +17 -0
- package/dist/web/lib/modal-open-focus.js +44 -0
- package/dist/web/lib/restore-focus.d.ts +12 -0
- package/dist/web/lib/restore-focus.js +32 -0
- package/dist/web/lib/utils.d.ts +4 -0
- package/dist/web/lib/utils.js +10 -0
- package/dist/web/styles.css +162 -0
- package/package.json +205 -4
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { FONT_KEYS, FONT_TOKEN, RADIUS_ROLES } from "./types.js";
|
|
2
|
+
import { bodyLineHeight, colorValue, normalize } from "./model.js";
|
|
3
|
+
|
|
4
|
+
//#region src/tuning/css.ts
|
|
5
|
+
/** 影の preset(Tailwind の既定の影)。love3 の既定は `--shadow-color` を使う淡い影(`definition.ts` の `theme`)。 */
|
|
6
|
+
const SHADOW_PRESET = {
|
|
7
|
+
"2xs": "0 1px rgb(0 0 0 / 0.05)",
|
|
8
|
+
xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
|
9
|
+
sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
|
|
10
|
+
md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
|
11
|
+
lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
|
|
12
|
+
xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
|
|
13
|
+
"2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)"
|
|
14
|
+
};
|
|
15
|
+
/** 影を消す preset(`SHADOW_PRESET` と同じ段)。 */
|
|
16
|
+
const SHADOW_NONE = {
|
|
17
|
+
"2xs": "none",
|
|
18
|
+
xs: "none",
|
|
19
|
+
sm: "none",
|
|
20
|
+
md: "none",
|
|
21
|
+
lg: "none",
|
|
22
|
+
xl: "none",
|
|
23
|
+
"2xl": "none"
|
|
24
|
+
};
|
|
25
|
+
/** 調整で差し替える影の値。既定(`default`)は差し替えない。 */
|
|
26
|
+
function shadowValues(n) {
|
|
27
|
+
if (n.shadow === "default") return [];
|
|
28
|
+
return Object.entries(n.shadow === "none" ? SHADOW_NONE : SHADOW_PRESET);
|
|
29
|
+
}
|
|
30
|
+
/** 変えた色のトークン名(ライト・ダークのどちらかで変えたもの)。定義の順。 */
|
|
31
|
+
function touchedColors(n, catalog) {
|
|
32
|
+
return catalog.colors.map((color) => color.name).filter((name) => n.tokens.light[name] !== void 0 || n.tokens.dark[name] !== void 0);
|
|
33
|
+
}
|
|
34
|
+
function decl(name, value) {
|
|
35
|
+
return ` --${name}: ${value};`;
|
|
36
|
+
}
|
|
37
|
+
function block(selector, lines) {
|
|
38
|
+
return lines.length === 0 ? "" : `${selector} {\n${lines.join("\n")}\n}`;
|
|
39
|
+
}
|
|
40
|
+
/** 既定と違う役割(`normalize` 済みなので、`radius` に残っているのが差分)。 */
|
|
41
|
+
function radiusRoles(n) {
|
|
42
|
+
return RADIUS_ROLES.flatMap((role) => {
|
|
43
|
+
const px = n.radius[role];
|
|
44
|
+
return px === void 0 ? [] : [[`radius-${role}`, `${px}px`]];
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* **実行時に `<style id="love3-tuning">` へ差し込む CSS。** 既定どおりなら空文字(差し込まない)。
|
|
49
|
+
*
|
|
50
|
+
* love3 の生成 CSS と同じ形(`:root` がライト・`.dark` がダーク)で、後から読み込んで上書きする。
|
|
51
|
+
* - 変えた色は、**ライトとダークの両方を書く**。生成 CSS は `:root` の後に `.dark` が来るので、ライトだけを上書きすると、
|
|
52
|
+
* 後ろに置いた `:root` が生成の `.dark` に勝ってダークまで潰れる。`.dark` にも実効値を書いて、ダークは別に守る
|
|
53
|
+
* - セマンティックの参照・角丸・書体・本文サイズは `:root` だけ(生成の `.dark` は色のトークンしか再定義しない)
|
|
54
|
+
* - 角丸(`--radius-control` / `--radius-surface`)は Tailwind の `@theme` の変数だが実行時は `:root` の変数として効く。
|
|
55
|
+
* 影は Tailwind がクラスに畳み込む(`.shadow-md { --tw-shadow: … }`)ので、クラスごとに `--tw-shadow` を上書きする
|
|
56
|
+
*/
|
|
57
|
+
function toRuntimeCss(tuning, catalog) {
|
|
58
|
+
const n = normalize(tuning, catalog);
|
|
59
|
+
const touched = touchedColors(n, catalog);
|
|
60
|
+
const root = [];
|
|
61
|
+
const dark = [];
|
|
62
|
+
for (const name of touched) {
|
|
63
|
+
root.push(decl(name, colorValue(n, catalog, "light", name)));
|
|
64
|
+
if (catalog.colors.find((color) => color.name === name)?.hasDark === true) dark.push(decl(name, colorValue(n, catalog, "dark", name)));
|
|
65
|
+
}
|
|
66
|
+
for (const [name, ref] of Object.entries(n.semantic)) root.push(decl(name, `var(--${ref})`));
|
|
67
|
+
for (const [name, value] of radiusRoles(n)) root.push(decl(name, value));
|
|
68
|
+
for (const key of FONT_KEYS) {
|
|
69
|
+
const value = n.font[key];
|
|
70
|
+
if (value !== void 0) root.push(decl(FONT_TOKEN[key], value));
|
|
71
|
+
}
|
|
72
|
+
if (n.font.bodySize !== void 0) {
|
|
73
|
+
root.push(decl("text-body", `${n.font.bodySize}px`));
|
|
74
|
+
root.push(decl("text-body--line-height", `${bodyLineHeight(catalog, n.font.bodySize)}px`));
|
|
75
|
+
}
|
|
76
|
+
const parts = [block(":root", root), block(".dark", dark)];
|
|
77
|
+
for (const [step, value] of shadowValues(n)) parts.push(block(`.shadow-${step}`, [` --tw-shadow: ${value};`]));
|
|
78
|
+
return parts.filter((part) => part !== "").join("\n");
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* **コピー用の CSS。** `styles.gen.css` と同じ書式で、既定との差分だけ(`:root` / `.dark` / `@theme`)。
|
|
82
|
+
* `@theme` は Tailwind のビルド時の変数(角丸・影・本文サイズ)で、`styles.gen.css` では `definition.ts` の `theme` から出る。
|
|
83
|
+
* 実行時に効かせる CSS(`toRuntimeCss`)とは別物(そちらは `@theme` を使えない)。
|
|
84
|
+
*/
|
|
85
|
+
function toExportCss(tuning, catalog) {
|
|
86
|
+
const n = normalize(tuning, catalog);
|
|
87
|
+
const root = [];
|
|
88
|
+
const dark = [];
|
|
89
|
+
for (const color of catalog.colors) {
|
|
90
|
+
const light = n.tokens.light[color.name];
|
|
91
|
+
if (light !== void 0) root.push(decl(color.name, light));
|
|
92
|
+
const night = n.tokens.dark[color.name];
|
|
93
|
+
if (night !== void 0) dark.push(decl(color.name, night));
|
|
94
|
+
}
|
|
95
|
+
for (const [name, ref] of Object.entries(n.semantic)) root.push(decl(name, `var(--${ref})`));
|
|
96
|
+
for (const key of FONT_KEYS) {
|
|
97
|
+
const value = n.font[key];
|
|
98
|
+
if (value !== void 0) root.push(decl(FONT_TOKEN[key], value));
|
|
99
|
+
}
|
|
100
|
+
const theme = radiusRoles(n).map(([name, value]) => decl(name, value));
|
|
101
|
+
for (const [step, value] of shadowValues(n)) theme.push(decl(`shadow-${step}`, value));
|
|
102
|
+
if (n.font.bodySize !== void 0) {
|
|
103
|
+
theme.push(decl("text-body", `${n.font.bodySize}px`));
|
|
104
|
+
theme.push(decl("text-body--line-height", `${bodyLineHeight(catalog, n.font.bodySize)}px`));
|
|
105
|
+
}
|
|
106
|
+
return [
|
|
107
|
+
block(":root", root),
|
|
108
|
+
block(".dark", dark),
|
|
109
|
+
block("@theme", theme)
|
|
110
|
+
].filter((part) => part !== "").join("\n\n");
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* **`definition.ts` に取り込むための差分。** SSOT のトークンの行(`{ name, value, dark }`)と、`theme` の行の形で、
|
|
114
|
+
* 変えた項目だけを出す。名前は変えず、値を差し替える(トークンの直し方)。取り込んだら `bun run generate`。
|
|
115
|
+
*/
|
|
116
|
+
function toDefinitionDiff(tuning, catalog) {
|
|
117
|
+
const n = normalize(tuning, catalog);
|
|
118
|
+
const lines = [];
|
|
119
|
+
const tokenLines = [];
|
|
120
|
+
for (const color of catalog.colors) {
|
|
121
|
+
if (n.tokens.light[color.name] === void 0 && n.tokens.dark[color.name] === void 0) continue;
|
|
122
|
+
const fields = [`name: ${JSON.stringify(color.name)}`, `value: ${JSON.stringify(colorValue(n, catalog, "light", color.name))}`];
|
|
123
|
+
if (color.hasDark) fields.push(`dark: ${JSON.stringify(colorValue(n, catalog, "dark", color.name))}`);
|
|
124
|
+
fields.push("color: true");
|
|
125
|
+
tokenLines.push(`{ ${fields.join(", ")} },`);
|
|
126
|
+
}
|
|
127
|
+
for (const [name, ref] of Object.entries(n.semantic)) tokenLines.push(`{ name: ${JSON.stringify(name)}, value: ${JSON.stringify(`var(--${ref})`)}, color: true },`);
|
|
128
|
+
for (const key of FONT_KEYS) {
|
|
129
|
+
const value = n.font[key];
|
|
130
|
+
if (value !== void 0) tokenLines.push(`{ name: ${JSON.stringify(FONT_TOKEN[key])}, value: ${JSON.stringify(value)} },`);
|
|
131
|
+
}
|
|
132
|
+
if (tokenLines.length > 0) lines.push("// groups[].tokens の該当する行を、次の値に差し替える", ...tokenLines);
|
|
133
|
+
const themeLines = radiusRoles(n).map(([name, value]) => `${JSON.stringify(name)}: ${JSON.stringify(value)},`);
|
|
134
|
+
for (const [step, value] of shadowValues(n)) themeLines.push(`${JSON.stringify(`shadow-${step}`)}: ${JSON.stringify(value)},`);
|
|
135
|
+
if (n.font.bodySize !== void 0) {
|
|
136
|
+
themeLines.push(`"text-body": ${JSON.stringify(`${n.font.bodySize}px`)},`);
|
|
137
|
+
themeLines.push(`"text-body--line-height": ${JSON.stringify(`${bodyLineHeight(catalog, n.font.bodySize)}px`)},`);
|
|
138
|
+
}
|
|
139
|
+
if (themeLines.length > 0) {
|
|
140
|
+
if (lines.length > 0) lines.push("");
|
|
141
|
+
lines.push("// theme の該当する行を、次の値に差し替える", ...themeLines);
|
|
142
|
+
}
|
|
143
|
+
return lines.join("\n");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
//#endregion
|
|
147
|
+
export { SHADOW_PRESET, toDefinitionDiff, toExportCss, toRuntimeCss };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BODY_SIZE_MAX, BODY_SIZE_MIN, ColorGroup, ColorToken, FONT_KEYS, FONT_TOKEN, FontKey, MODES, Mode, RADIUS_MAX, RADIUS_ROLES, RadiusRole, ShadowPreset, Tuning, TuningCatalog, emptyTuning } from "./types.js";
|
|
2
|
+
import { buildCatalog, buildCatalogSafe, findColor } from "./catalog.js";
|
|
3
|
+
import { ColorResult, parseTokenColor } from "./color.js";
|
|
4
|
+
import { SHADOW_PRESET, toDefinitionDiff, toExportCss, toRuntimeCss } from "./css.js";
|
|
5
|
+
import { bodyLineHeight, colorValue, countChanges, defaultFont, effectiveTokens, isEmpty, modeOf, normalize, radiusPx, withBodySize, withColor, withFont, withRadius, withSemantic, withShadow } from "./model.js";
|
|
6
|
+
import { NATIVE_BUILD_FIXED_BRAND_TOKENS, NATIVE_BUILD_FIXED_TOKENS, firstFontFamily, nativeLimits, toNativeVariables } from "./native.js";
|
|
7
|
+
import { Envelope, FORMAT, MAX_ENTRIES, MAX_IMPORT_BYTES, MAX_REASONS, ParseResult, STORAGE_KEY, TOO_LARGE_REASON, VERSION, fontProblem, parseTuning, toExportObject, toJson, tooLarge } from "./schema.js";
|
|
8
|
+
export { BODY_SIZE_MAX, BODY_SIZE_MIN, ColorGroup, ColorResult, ColorToken, type Envelope, FONT_KEYS, FONT_TOKEN, FORMAT, FontKey, MAX_ENTRIES, MAX_IMPORT_BYTES, MAX_REASONS, MODES, Mode, NATIVE_BUILD_FIXED_BRAND_TOKENS, NATIVE_BUILD_FIXED_TOKENS, ParseResult, RADIUS_MAX, RADIUS_ROLES, RadiusRole, SHADOW_PRESET, STORAGE_KEY, ShadowPreset, TOO_LARGE_REASON, Tuning, TuningCatalog, VERSION, bodyLineHeight, buildCatalog, buildCatalogSafe, colorValue, countChanges, defaultFont, effectiveTokens, emptyTuning, findColor, firstFontFamily, fontProblem, isEmpty, modeOf, nativeLimits, normalize, parseTokenColor, parseTuning, radiusPx, toDefinitionDiff, toExportCss, toExportObject, toJson, toNativeVariables, toRuntimeCss, tooLarge, withBodySize, withColor, withFont, withRadius, withSemantic, withShadow };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { buildCatalog, buildCatalogSafe, findColor } from "./catalog.js";
|
|
2
|
+
import { parseTokenColor } from "./color.js";
|
|
3
|
+
import { BODY_SIZE_MAX, BODY_SIZE_MIN, FONT_KEYS, FONT_TOKEN, MODES, RADIUS_MAX, RADIUS_ROLES, emptyTuning } from "./types.js";
|
|
4
|
+
import { bodyLineHeight, colorValue, countChanges, defaultFont, effectiveTokens, isEmpty, modeOf, normalize, radiusPx, withBodySize, withColor, withFont, withRadius, withSemantic, withShadow } from "./model.js";
|
|
5
|
+
import { SHADOW_PRESET, toDefinitionDiff, toExportCss, toRuntimeCss } from "./css.js";
|
|
6
|
+
import { NATIVE_BUILD_FIXED_BRAND_TOKENS, NATIVE_BUILD_FIXED_TOKENS, firstFontFamily, nativeLimits, toNativeVariables } from "./native.js";
|
|
7
|
+
import { FORMAT, MAX_ENTRIES, MAX_IMPORT_BYTES, MAX_REASONS, STORAGE_KEY, TOO_LARGE_REASON, VERSION, fontProblem, parseTuning, toExportObject, toJson, tooLarge } from "./schema.js";
|
|
8
|
+
|
|
9
|
+
export { BODY_SIZE_MAX, BODY_SIZE_MIN, FONT_KEYS, FONT_TOKEN, FORMAT, MAX_ENTRIES, MAX_IMPORT_BYTES, MAX_REASONS, MODES, NATIVE_BUILD_FIXED_BRAND_TOKENS, NATIVE_BUILD_FIXED_TOKENS, RADIUS_MAX, RADIUS_ROLES, SHADOW_PRESET, STORAGE_KEY, TOO_LARGE_REASON, VERSION, bodyLineHeight, buildCatalog, buildCatalogSafe, colorValue, countChanges, defaultFont, effectiveTokens, emptyTuning, findColor, firstFontFamily, fontProblem, isEmpty, modeOf, nativeLimits, normalize, parseTokenColor, parseTuning, radiusPx, toDefinitionDiff, toExportCss, toExportObject, toJson, toNativeVariables, toRuntimeCss, tooLarge, withBodySize, withColor, withFont, withRadius, withSemantic, withShadow };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FontKey, Mode, RadiusRole, ShadowPreset, Tuning, TuningCatalog } from "./types.js";
|
|
2
|
+
//#region src/tuning/model.d.ts
|
|
3
|
+
/** 色のトークンを実際に持つモード。ブランド色は共通なので、ダークの指定は `light` に寄せる。 */
|
|
4
|
+
export declare function modeOf(catalog: TuningCatalog, name: string, mode: Mode): Mode;
|
|
5
|
+
/** 既定のフォント値。 */
|
|
6
|
+
export declare function defaultFont(catalog: TuningCatalog, key: FontKey): string;
|
|
7
|
+
/** 役割ごとの角丸(px)。指定が無ければ既定(control 6・surface 10)。 */
|
|
8
|
+
export declare function radiusPx(tuning: Tuning, catalog: TuningCatalog, role: RadiusRole): number;
|
|
9
|
+
/** 本文の行の高さ(px)。サイズに比例させる(既定の 14px / 22px の比)。 */
|
|
10
|
+
export declare function bodyLineHeight(catalog: TuningCatalog, size: number): number;
|
|
11
|
+
/**
|
|
12
|
+
* 既定と同じ値の項目を落として、同じ内容が 1 通りの形になるようにする(保存・エクスポート・比較の前に通す)。
|
|
13
|
+
* 色は正規の形(小文字の `#rrggbb`)にそろえる。読めない色は落とさずそのまま残す(検証は `parseTuning` の仕事)。
|
|
14
|
+
*/
|
|
15
|
+
export declare function normalize(tuning: Tuning, catalog: TuningCatalog): Tuning;
|
|
16
|
+
/** 既定と同じ(差分が無い)か。 */
|
|
17
|
+
export declare function isEmpty(tuning: Tuning, catalog: TuningCatalog): boolean;
|
|
18
|
+
/** 既定との差分の数(色・参照先・角丸・書体・影の項目ごとに 1)。 */
|
|
19
|
+
export declare function countChanges(tuning: Tuning, catalog: TuningCatalog): number;
|
|
20
|
+
/**
|
|
21
|
+
* トークンの実値。**参照(`var()`)をたどる**: セマンティックトークンは参照先(上書きがあればそれ、無ければ既定)の実値になる。
|
|
22
|
+
* 参照先のランプを調整すれば、それを指すセマンティックトークンも変わる(実行時の CSS と同じ解決)。
|
|
23
|
+
*/
|
|
24
|
+
export declare function colorValue(tuning: Tuning, catalog: TuningCatalog, mode: Mode, name: string): string;
|
|
25
|
+
/** 全トークン(色・書体・調整した角丸)の実値の表。調整を重ねた後の値で、`tokens` と同じ形。 */
|
|
26
|
+
export declare function effectiveTokens(tuning: Tuning, catalog: TuningCatalog): Record<Mode, Record<string, string>>;
|
|
27
|
+
export declare function withColor(tuning: Tuning, catalog: TuningCatalog, mode: Mode, name: string, value: string | undefined): Tuning;
|
|
28
|
+
export declare function withSemantic(tuning: Tuning, name: string, ref: string | undefined): Tuning;
|
|
29
|
+
export declare function withRadius(tuning: Tuning, role: RadiusRole, px: number | undefined): Tuning;
|
|
30
|
+
export declare function withFont(tuning: Tuning, key: FontKey, value: string | undefined): Tuning;
|
|
31
|
+
export declare function withBodySize(tuning: Tuning, size: number | undefined): Tuning;
|
|
32
|
+
export declare function withShadow(tuning: Tuning, shadow: ShadowPreset): Tuning;
|
|
33
|
+
//#endregion
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { parseTokenColor } from "./color.js";
|
|
2
|
+
import { FONT_KEYS, FONT_TOKEN, MODES, RADIUS_ROLES, emptyTuning } from "./types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/tuning/model.ts
|
|
5
|
+
/** 色のトークンを実際に持つモード。ブランド色は共通なので、ダークの指定は `light` に寄せる。 */
|
|
6
|
+
function modeOf(catalog, name, mode) {
|
|
7
|
+
return mode === "dark" && catalog.colors.find((color) => color.name === name)?.hasDark === false ? "light" : mode;
|
|
8
|
+
}
|
|
9
|
+
/** 既定のフォント値。 */
|
|
10
|
+
function defaultFont(catalog, key) {
|
|
11
|
+
return catalog.defaults.light[FONT_TOKEN[key]] ?? "";
|
|
12
|
+
}
|
|
13
|
+
/** 役割ごとの角丸(px)。指定が無ければ既定(control 6・surface 10)。 */
|
|
14
|
+
function radiusPx(tuning, catalog, role) {
|
|
15
|
+
return tuning.radius[role] ?? catalog.radius[role];
|
|
16
|
+
}
|
|
17
|
+
/** 本文の行の高さ(px)。サイズに比例させる(既定の 14px / 22px の比)。 */
|
|
18
|
+
function bodyLineHeight(catalog, size) {
|
|
19
|
+
return Math.round(size * catalog.body.lineHeight / catalog.body.size);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 既定と同じ値の項目を落として、同じ内容が 1 通りの形になるようにする(保存・エクスポート・比較の前に通す)。
|
|
23
|
+
* 色は正規の形(小文字の `#rrggbb`)にそろえる。読めない色は落とさずそのまま残す(検証は `parseTuning` の仕事)。
|
|
24
|
+
*/
|
|
25
|
+
function normalize(tuning, catalog) {
|
|
26
|
+
const out = emptyTuning();
|
|
27
|
+
for (const mode of MODES) for (const color of catalog.colors) {
|
|
28
|
+
const raw = tuning.tokens[mode][color.name];
|
|
29
|
+
if (raw === void 0) continue;
|
|
30
|
+
if (mode === "dark" && !color.hasDark) continue;
|
|
31
|
+
const parsed = parseTokenColor(raw, { alpha: color.alpha });
|
|
32
|
+
const value = parsed.ok ? parsed.value : raw;
|
|
33
|
+
const fallback = catalog.defaults[mode][color.name];
|
|
34
|
+
if (value !== (fallback === void 0 ? void 0 : toCanonical(fallback, color.alpha))) out.tokens[mode][color.name] = value;
|
|
35
|
+
}
|
|
36
|
+
for (const [name, ref] of Object.entries(tuning.semantic)) if (Object.hasOwn(catalog.semantic, name) && ref !== catalog.semantic[name]) out.semantic[name] = ref;
|
|
37
|
+
for (const role of RADIUS_ROLES) {
|
|
38
|
+
const px = tuning.radius[role];
|
|
39
|
+
if (px !== void 0 && px !== catalog.radius[role]) out.radius[role] = px;
|
|
40
|
+
}
|
|
41
|
+
for (const key of FONT_KEYS) {
|
|
42
|
+
const value = tuning.font[key];
|
|
43
|
+
if (value !== void 0 && value !== defaultFont(catalog, key)) out.font[key] = value;
|
|
44
|
+
}
|
|
45
|
+
if (tuning.font.bodySize !== void 0 && tuning.font.bodySize !== catalog.body.size) out.font.bodySize = tuning.font.bodySize;
|
|
46
|
+
out.shadow = tuning.shadow;
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
function toCanonical(value, alpha) {
|
|
50
|
+
const parsed = parseTokenColor(value, { alpha });
|
|
51
|
+
return parsed.ok ? parsed.value : value;
|
|
52
|
+
}
|
|
53
|
+
/** 既定と同じ(差分が無い)か。 */
|
|
54
|
+
function isEmpty(tuning, catalog) {
|
|
55
|
+
return countChanges(tuning, catalog) === 0;
|
|
56
|
+
}
|
|
57
|
+
/** 既定との差分の数(色・参照先・角丸・書体・影の項目ごとに 1)。 */
|
|
58
|
+
function countChanges(tuning, catalog) {
|
|
59
|
+
const n = normalize(tuning, catalog);
|
|
60
|
+
return Object.keys(n.tokens.light).length + Object.keys(n.tokens.dark).length + Object.keys(n.semantic).length + Object.keys(n.radius).length + Object.keys(n.font).length + (n.shadow === "default" ? 0 : 1);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* トークンの実値。**参照(`var()`)をたどる**: セマンティックトークンは参照先(上書きがあればそれ、無ければ既定)の実値になる。
|
|
64
|
+
* 参照先のランプを調整すれば、それを指すセマンティックトークンも変わる(実行時の CSS と同じ解決)。
|
|
65
|
+
*/
|
|
66
|
+
function colorValue(tuning, catalog, mode, name) {
|
|
67
|
+
const ref = (Object.hasOwn(tuning.semantic, name) ? tuning.semantic[name] : void 0) ?? (Object.hasOwn(catalog.semantic, name) ? catalog.semantic[name] : void 0);
|
|
68
|
+
if (ref !== void 0) return colorValue(tuning, catalog, mode, ref);
|
|
69
|
+
const owner = modeOf(catalog, name, mode);
|
|
70
|
+
const override = Object.hasOwn(tuning.tokens[owner], name) ? tuning.tokens[owner][name] : void 0;
|
|
71
|
+
if (override !== void 0) return override;
|
|
72
|
+
const fallback = Object.hasOwn(catalog.defaults[mode], name) ? catalog.defaults[mode][name] : void 0;
|
|
73
|
+
if (fallback === void 0) throw new Error(`未定義のトークン: --${name}`);
|
|
74
|
+
return fallback;
|
|
75
|
+
}
|
|
76
|
+
/** 全トークン(色・書体・調整した角丸)の実値の表。調整を重ねた後の値で、`tokens` と同じ形。 */
|
|
77
|
+
function effectiveTokens(tuning, catalog) {
|
|
78
|
+
const out = {
|
|
79
|
+
light: {},
|
|
80
|
+
dark: {}
|
|
81
|
+
};
|
|
82
|
+
for (const mode of MODES) {
|
|
83
|
+
for (const [name, value] of Object.entries(catalog.defaults[mode])) {
|
|
84
|
+
const isColor = catalog.colors.some((color) => color.name === name) || Object.hasOwn(catalog.semantic, name);
|
|
85
|
+
out[mode][name] = isColor ? colorValue(tuning, catalog, mode, name) : value;
|
|
86
|
+
}
|
|
87
|
+
for (const key of FONT_KEYS) out[mode][FONT_TOKEN[key]] = tuning.font[key] ?? defaultFont(catalog, key);
|
|
88
|
+
out[mode]["font-mono"] = out[mode]["font-geist-mono"] ?? "";
|
|
89
|
+
for (const role of RADIUS_ROLES) {
|
|
90
|
+
const px = tuning.radius[role];
|
|
91
|
+
if (px !== void 0) out[mode][`radius-${role}`] = `${px}px`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
function withColor(tuning, catalog, mode, name, value) {
|
|
97
|
+
const owner = modeOf(catalog, name, mode);
|
|
98
|
+
const table = { ...tuning.tokens[owner] };
|
|
99
|
+
if (value === void 0) delete table[name];
|
|
100
|
+
else table[name] = value;
|
|
101
|
+
return {
|
|
102
|
+
...tuning,
|
|
103
|
+
tokens: {
|
|
104
|
+
...tuning.tokens,
|
|
105
|
+
[owner]: table
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function withSemantic(tuning, name, ref) {
|
|
110
|
+
const semantic = { ...tuning.semantic };
|
|
111
|
+
if (ref === void 0) delete semantic[name];
|
|
112
|
+
else semantic[name] = ref;
|
|
113
|
+
return {
|
|
114
|
+
...tuning,
|
|
115
|
+
semantic
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function withRadius(tuning, role, px) {
|
|
119
|
+
const radius = { ...tuning.radius };
|
|
120
|
+
if (px === void 0) delete radius[role];
|
|
121
|
+
else radius[role] = px;
|
|
122
|
+
return {
|
|
123
|
+
...tuning,
|
|
124
|
+
radius
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function withFont(tuning, key, value) {
|
|
128
|
+
const font = { ...tuning.font };
|
|
129
|
+
if (value === void 0) delete font[key];
|
|
130
|
+
else font[key] = value;
|
|
131
|
+
return {
|
|
132
|
+
...tuning,
|
|
133
|
+
font
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function withBodySize(tuning, size) {
|
|
137
|
+
const { bodySize: _previous, ...rest } = tuning.font;
|
|
138
|
+
return {
|
|
139
|
+
...tuning,
|
|
140
|
+
font: size === void 0 ? rest : {
|
|
141
|
+
...rest,
|
|
142
|
+
bodySize: size
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function withShadow(tuning, shadow) {
|
|
147
|
+
return {
|
|
148
|
+
...tuning,
|
|
149
|
+
shadow
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
//#endregion
|
|
154
|
+
export { bodyLineHeight, colorValue, countChanges, defaultFont, effectiveTokens, isEmpty, modeOf, normalize, radiusPx, withBodySize, withColor, withFont, withRadius, withSemantic, withShadow };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Mode, Tuning, TuningCatalog } from "./types.js";
|
|
2
|
+
//#region src/tuning/native.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* ライト・ダークで**同じ値**のトークン(`.dark` で再定義しない)と、それを指すエイリアス。
|
|
5
|
+
* react-native-css は、1 度しか宣言されない変数を**ビルド時にリテラルへ畳み込む**ので、`bg-action` などのクラスは
|
|
6
|
+
* 実機で CSS 変数を引かず、**実行時の上書き(`toNativeVariables`)に追従しない**。TS から色を引く `useTokenColor` は追従する。
|
|
7
|
+
* 一覧が `definition.ts` と食い違わないことは、`native/lib/tokens.test.ts` が見る。
|
|
8
|
+
*/
|
|
9
|
+
export declare const NATIVE_BUILD_FIXED_TOKENS: readonly ["action", "action-hover", "action-foreground", "primary", "primary-foreground", "ring", "sidebar-primary", "sidebar-primary-foreground", "sidebar-ring", "destructive-solid-foreground"];
|
|
10
|
+
/**
|
|
11
|
+
* ブランド色(`lt-three`・`lt-three-foreground`)。ライト・ダーク共通でビルド時に固定され、`bg-lt-three` などのクラスは
|
|
12
|
+
* 実行時の上書きに追従しない(テーマで反転させないための仕様)。`NATIVE_BUILD_FIXED_TOKENS` とは別に持つのは、
|
|
13
|
+
* `native/lib/tokens-check.ts` の畳み込み検査がブランド色を別扱いしているため(一覧の検査と食い違わせない)。
|
|
14
|
+
*/
|
|
15
|
+
export declare const NATIVE_BUILD_FIXED_BRAND_TOKENS: readonly ["lt-three", "lt-three-foreground"];
|
|
16
|
+
/** 書体の値(CSS の font-family の並び)の先頭の名前。RN の `fontFamily` は 1 つの名前しか取らない。`var()` なら undefined。 */
|
|
17
|
+
export declare function firstFontFamily(value: string): string | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* native に配る CSS 変数(react-native-css の `VariableContextProvider` の `value`)。指定したモードの、**既定と違うものだけ**。
|
|
20
|
+
* - 色のトークン: 実効値(セマンティックの参照も解決した値)。ランプの変更に依存するセマンティックトークンも、同じ変更の下で
|
|
21
|
+
* 別のリテラルとして載せる(react-native-web では `--card: var(--raised)` が `:root` で解決済みで、ランプの上書きだけでは追従しないため)
|
|
22
|
+
* - 角丸(`--radius-control` / `--radius-surface`): px
|
|
23
|
+
* - 書体(`--font-geist` など): 先頭の名前だけ
|
|
24
|
+
*
|
|
25
|
+
* **実機で効くのは、ライト・ダークで値が違う色のトークンを使うクラス(`bg-card` など。実機ではランプへの参照になる)と書体**。
|
|
26
|
+
* 角丸・本文サイズはビルド時にリテラルへ畳み込まれ、`NATIVE_BUILD_FIXED_TOKENS` の色のクラスも畳み込まれるので、実機では効かない
|
|
27
|
+
* (react-native-web では CSS 変数なので効く)。何が効かないかは `nativeLimits` が返す。
|
|
28
|
+
*/
|
|
29
|
+
export declare function toNativeVariables(tuning: Tuning, catalog: TuningCatalog, mode: Mode): Record<`--${string}`, string>;
|
|
30
|
+
/**
|
|
31
|
+
* 調整のうち、**native の実機では実行時に効かない項目**の説明(日本語)。空なら全部効く(react-native-web では全部効く)。
|
|
32
|
+
* 調整の画面に出して、「効かないのは仕様」と分かるようにする。値は JSON に残るので、web で読めば効く。
|
|
33
|
+
*/
|
|
34
|
+
export declare function nativeLimits(tuning: Tuning, catalog: TuningCatalog): string[];
|
|
35
|
+
//#endregion
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { FONT_KEYS, FONT_TOKEN, RADIUS_ROLES } from "./types.js";
|
|
2
|
+
import { effectiveTokens, normalize } from "./model.js";
|
|
3
|
+
|
|
4
|
+
//#region src/tuning/native.ts
|
|
5
|
+
/**
|
|
6
|
+
* ライト・ダークで**同じ値**のトークン(`.dark` で再定義しない)と、それを指すエイリアス。
|
|
7
|
+
* react-native-css は、1 度しか宣言されない変数を**ビルド時にリテラルへ畳み込む**ので、`bg-action` などのクラスは
|
|
8
|
+
* 実機で CSS 変数を引かず、**実行時の上書き(`toNativeVariables`)に追従しない**。TS から色を引く `useTokenColor` は追従する。
|
|
9
|
+
* 一覧が `definition.ts` と食い違わないことは、`native/lib/tokens.test.ts` が見る。
|
|
10
|
+
*/
|
|
11
|
+
const NATIVE_BUILD_FIXED_TOKENS = [
|
|
12
|
+
"action",
|
|
13
|
+
"action-hover",
|
|
14
|
+
"action-foreground",
|
|
15
|
+
"primary",
|
|
16
|
+
"primary-foreground",
|
|
17
|
+
"ring",
|
|
18
|
+
"sidebar-primary",
|
|
19
|
+
"sidebar-primary-foreground",
|
|
20
|
+
"sidebar-ring",
|
|
21
|
+
"destructive-solid-foreground"
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* ブランド色(`lt-three`・`lt-three-foreground`)。ライト・ダーク共通でビルド時に固定され、`bg-lt-three` などのクラスは
|
|
25
|
+
* 実行時の上書きに追従しない(テーマで反転させないための仕様)。`NATIVE_BUILD_FIXED_TOKENS` とは別に持つのは、
|
|
26
|
+
* `native/lib/tokens-check.ts` の畳み込み検査がブランド色を別扱いしているため(一覧の検査と食い違わせない)。
|
|
27
|
+
*/
|
|
28
|
+
const NATIVE_BUILD_FIXED_BRAND_TOKENS = ["lt-three", "lt-three-foreground"];
|
|
29
|
+
/** 書体の値(CSS の font-family の並び)の先頭の名前。RN の `fontFamily` は 1 つの名前しか取らない。`var()` なら undefined。 */
|
|
30
|
+
function firstFontFamily(value) {
|
|
31
|
+
const first = value.split(",")[0]?.trim() ?? "";
|
|
32
|
+
if (first === "" || first.startsWith("var(")) return void 0;
|
|
33
|
+
return first.replace(/^["']|["']$/g, "");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* native に配る CSS 変数(react-native-css の `VariableContextProvider` の `value`)。指定したモードの、**既定と違うものだけ**。
|
|
37
|
+
* - 色のトークン: 実効値(セマンティックの参照も解決した値)。ランプの変更に依存するセマンティックトークンも、同じ変更の下で
|
|
38
|
+
* 別のリテラルとして載せる(react-native-web では `--card: var(--raised)` が `:root` で解決済みで、ランプの上書きだけでは追従しないため)
|
|
39
|
+
* - 角丸(`--radius-control` / `--radius-surface`): px
|
|
40
|
+
* - 書体(`--font-geist` など): 先頭の名前だけ
|
|
41
|
+
*
|
|
42
|
+
* **実機で効くのは、ライト・ダークで値が違う色のトークンを使うクラス(`bg-card` など。実機ではランプへの参照になる)と書体**。
|
|
43
|
+
* 角丸・本文サイズはビルド時にリテラルへ畳み込まれ、`NATIVE_BUILD_FIXED_TOKENS` の色のクラスも畳み込まれるので、実機では効かない
|
|
44
|
+
* (react-native-web では CSS 変数なので効く)。何が効かないかは `nativeLimits` が返す。
|
|
45
|
+
*/
|
|
46
|
+
function toNativeVariables(tuning, catalog, mode) {
|
|
47
|
+
const n = normalize(tuning, catalog);
|
|
48
|
+
const effective = effectiveTokens(n, catalog)[mode];
|
|
49
|
+
const out = {};
|
|
50
|
+
const isColor = (name) => catalog.colors.some((color) => color.name === name) || Object.hasOwn(catalog.semantic, name);
|
|
51
|
+
for (const [name, value] of Object.entries(effective)) if (isColor(name) && value !== catalog.defaults[mode][name]) out[`--${name}`] = value;
|
|
52
|
+
for (const role of RADIUS_ROLES) {
|
|
53
|
+
const px = n.radius[role];
|
|
54
|
+
if (px !== void 0) out[`--radius-${role}`] = `${px}px`;
|
|
55
|
+
}
|
|
56
|
+
for (const key of FONT_KEYS) {
|
|
57
|
+
const family = n.font[key] === void 0 ? void 0 : firstFontFamily(n.font[key]);
|
|
58
|
+
if (family !== void 0) out[`--${FONT_TOKEN[key]}`] = family;
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 調整のうち、**native の実機では実行時に効かない項目**の説明(日本語)。空なら全部効く(react-native-web では全部効く)。
|
|
64
|
+
* 調整の画面に出して、「効かないのは仕様」と分かるようにする。値は JSON に残るので、web で読めば効く。
|
|
65
|
+
*/
|
|
66
|
+
function nativeLimits(tuning, catalog) {
|
|
67
|
+
const n = normalize(tuning, catalog);
|
|
68
|
+
const notes = [];
|
|
69
|
+
const fixed = /* @__PURE__ */ new Set([...NATIVE_BUILD_FIXED_TOKENS, ...NATIVE_BUILD_FIXED_BRAND_TOKENS]);
|
|
70
|
+
const touched = [.../* @__PURE__ */ new Set([...Object.keys(n.tokens.light), ...Object.keys(n.tokens.dark)])].filter((name) => fixed.has(name));
|
|
71
|
+
if (touched.length > 0) notes.push(`${touched.map((name) => `--${name}`).join("・")} は、実機ではビルド時に固定されるクラス(bg-action など)に効きません(TS から色を引く部品には効きます)`);
|
|
72
|
+
if (Object.keys(n.semantic).length > 0) notes.push("セマンティックトークンの参照先の変更は、実機ではクラスに効きません(ビルド時にランプへ解決されるため)");
|
|
73
|
+
if (Object.keys(n.radius).length > 0) notes.push("角丸は、実機ではビルド時に固定されるので効きません");
|
|
74
|
+
if (n.font.bodySize !== void 0) notes.push("本文サイズは、実機ではビルド時に固定されるので効きません");
|
|
75
|
+
if (n.shadow !== "default") notes.push("影の preset は native には適用しません");
|
|
76
|
+
return notes;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//#endregion
|
|
80
|
+
export { NATIVE_BUILD_FIXED_BRAND_TOKENS, NATIVE_BUILD_FIXED_TOKENS, firstFontFamily, nativeLimits, toNativeVariables };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Tuning, TuningCatalog } from "./types.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/tuning/schema.d.ts
|
|
4
|
+
/** エクスポート・保存の形式の名前とバージョン。形を変えたら `VERSION` を上げる。 */
|
|
5
|
+
export declare const FORMAT = "love3-tuning";
|
|
6
|
+
export declare const VERSION = 1;
|
|
7
|
+
/** 保存先(localStorage)のキー。 */
|
|
8
|
+
export declare const STORAGE_KEY = "love3-preview:tuning";
|
|
9
|
+
/**
|
|
10
|
+
* 形式の骨組み。**知らない項目は断る**(`strictObject`)。トークン名・色の中身など、DS に依存する検査は `parseTuning` が足す。
|
|
11
|
+
* 全部省略できる(既定との差分だけを書く)。
|
|
12
|
+
*/
|
|
13
|
+
declare const envelope: z.ZodObject<{
|
|
14
|
+
format: z.ZodLiteral<"love3-tuning">;
|
|
15
|
+
version: z.ZodLiteral<1>;
|
|
16
|
+
tokens: z.ZodOptional<z.ZodObject<{
|
|
17
|
+
light: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
18
|
+
dark: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
19
|
+
}, z.core.$strict>>;
|
|
20
|
+
radius: z.ZodOptional<z.ZodObject<{
|
|
21
|
+
control: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
surface: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
}, z.core.$strict>>;
|
|
24
|
+
semantic: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
25
|
+
font: z.ZodOptional<z.ZodObject<{
|
|
26
|
+
geist: z.ZodOptional<z.ZodString>;
|
|
27
|
+
geistMono: z.ZodOptional<z.ZodString>;
|
|
28
|
+
jp: z.ZodOptional<z.ZodString>;
|
|
29
|
+
bodySize: z.ZodOptional<z.ZodNumber>;
|
|
30
|
+
}, z.core.$strict>>;
|
|
31
|
+
shadow: z.ZodOptional<z.ZodEnum<{
|
|
32
|
+
default: "default";
|
|
33
|
+
none: "none";
|
|
34
|
+
preset: "preset";
|
|
35
|
+
}>>;
|
|
36
|
+
}, z.core.$strict>;
|
|
37
|
+
type Envelope = z.output<typeof envelope>;
|
|
38
|
+
/** 取り込む JSON の大きさの上限(バイト)。貼り付け・ファイルとも。 */
|
|
39
|
+
export declare const MAX_IMPORT_BYTES: number;
|
|
40
|
+
/** 1 つの表(`tokens.light` / `tokens.dark` / `semantic`)の項目数の上限。調整できる名前は 50 に満たない。 */
|
|
41
|
+
export declare const MAX_ENTRIES = 200;
|
|
42
|
+
/** 断る理由を、ここまで並べる(残りは「ほか N 件」)。 */
|
|
43
|
+
export declare const MAX_REASONS = 20;
|
|
44
|
+
/** 取り込もうとしている文字が、上限(`MAX_IMPORT_BYTES`)を超えるか。 */
|
|
45
|
+
export declare function tooLarge(text: string): boolean;
|
|
46
|
+
export declare const TOO_LARGE_REASON = "大きすぎます(256 KB まで)";
|
|
47
|
+
export declare function fontProblem(value: string): string | undefined;
|
|
48
|
+
export type ParseResult = {
|
|
49
|
+
ok: true;
|
|
50
|
+
tuning: Tuning;
|
|
51
|
+
} | {
|
|
52
|
+
ok: false;
|
|
53
|
+
reasons: string[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* エクスポートの JSON(文字列)を読んで検証する。**1 つでも不正なら全体を断る(部分適用しない)**。
|
|
57
|
+
* 断る理由は、見つけたものを全部、項目の場所つきの日本語で返す。
|
|
58
|
+
*
|
|
59
|
+
* 断るもの: JSON として読めない・`format` / `version` が違う・知らない項目・未知のトークン名(`--名前`)・
|
|
60
|
+
* 不正な色・ライト・ダーク共通のトークン(ブランド色)のダークの指定・未知のセマンティックトークン・選べない参照先・
|
|
61
|
+
* 範囲外の角丸と本文サイズ・差し込めない書体。成功したら、既定と同じ項目を落とした形(`normalize`)で返す。
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseTuning(text: string, catalog: TuningCatalog): ParseResult;
|
|
64
|
+
/** 差分だけのエクスポート用オブジェクト(空の節は省く)。 */
|
|
65
|
+
export declare function toExportObject(tuning: Tuning, catalog: TuningCatalog): Record<string, unknown>;
|
|
66
|
+
/** エクスポート・保存の JSON(既定との差分だけ。整形つき)。 */
|
|
67
|
+
export declare function toJson(tuning: Tuning, catalog: TuningCatalog): string;
|
|
68
|
+
//#endregion
|
|
69
|
+
export type { Envelope };
|