origam 2.8.1 → 2.9.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.
Files changed (48) hide show
  1. package/dist/src/assets/css/main.css +1 -1
  2. package/dist/src/assets/css/tokens/dark.css +32 -0
  3. package/dist/src/assets/css/tokens/light.css +16 -0
  4. package/dist/src/assets/scss/tokens/_dark.scss +16 -0
  5. package/dist/src/assets/scss/tokens/_light.scss +16 -0
  6. package/dist/src/components/Alert/OrigamAlert.vue +4 -2
  7. package/dist/src/components/Avatar/OrigamAvatarGroup.vue +31 -12
  8. package/dist/src/components/Btn/OrigamBtn.vue +11 -2
  9. package/dist/src/components/Btn/OrigamBtnGroup.vue +204 -22
  10. package/dist/src/components/Btn/OrigamBtnToggle.vue +5 -1
  11. package/dist/src/components/Card/OrigamCard.vue +5 -2
  12. package/dist/src/components/Checkbox/OrigamCheckbox.vue +3 -1
  13. package/dist/src/components/Chip/OrigamChip.vue +2 -0
  14. package/dist/src/components/Code/OrigamCode.vue +4 -2
  15. package/dist/src/components/ColorPickerField/OrigamColorPickerField.vue +19 -2
  16. package/dist/src/components/DatePickerField/OrigamDatePickerField.vue +3 -2
  17. package/dist/src/components/Dialog/OrigamDialog.vue +1 -1
  18. package/dist/src/components/Field/OrigamField.vue +7 -0
  19. package/dist/src/components/Layout/OrigamLayout.vue +10 -1
  20. package/dist/src/components/Menu/OrigamMenu.vue +3 -1
  21. package/dist/src/components/NumberField/OrigamNumberField.vue +3 -2
  22. package/dist/src/components/Overlay/OrigamOverlayScrim.vue +2 -0
  23. package/dist/src/components/Radio/OrigamRadio.vue +3 -1
  24. package/dist/src/components/Select/OrigamSelect.vue +3 -1
  25. package/dist/src/components/SelectionControl/OrigamSelectionControl.vue +2 -0
  26. package/dist/src/components/SliderField/OrigamSliderField.vue +3 -1
  27. package/dist/src/components/Snackbar/OrigamSnackbar.vue +3 -1
  28. package/dist/src/components/Snackbar/OrigamSnackbarItem.vue +2 -0
  29. package/dist/src/components/Switch/OrigamSwitch.vue +42 -1
  30. package/dist/src/components/Switch/OrigamSwitchTrack.vue +35 -2
  31. package/dist/src/components/Table/OrigamTable.vue +4 -2
  32. package/dist/src/components/Tabs/OrigamTabs.vue +3 -1
  33. package/dist/src/components/Tooltip/OrigamTooltip.vue +2 -0
  34. package/dist/src/composables/Commons/defaults.composable.cjs +10 -6
  35. package/dist/src/composables/Commons/defaults.composable.d.ts +30 -0
  36. package/dist/src/composables/Commons/defaults.composable.js +9 -6
  37. package/dist/src/composables/Theme/theme.composable.cjs +49 -30
  38. package/dist/src/composables/Theme/theme.composable.js +41 -22
  39. package/dist/src/interfaces/App/app.interface.d.ts +1 -1
  40. package/dist/src/interfaces/Btn/btn-group.interface.d.ts +2 -2
  41. package/dist/src/interfaces/Switch/switch-track.interface.d.ts +23 -6
  42. package/dist/src/themes/origam.theme.cjs +2 -4
  43. package/dist/src/themes/origam.theme.js +2 -2
  44. package/dist/src/types/tokens.type.d.ts +1 -1
  45. package/dist/src/utils/Commons/commons.util.cjs +10 -0
  46. package/dist/src/utils/Commons/commons.util.d.ts +18 -0
  47. package/dist/src/utils/Commons/commons.util.js +9 -0
  48. package/package.json +1 -1
@@ -5,24 +5,41 @@ import {
5
5
  ORIGAM_THEME_ATTR as ATTR,
6
6
  ORIGAM_THEME_STORAGE_KEY as STORAGE_KEY
7
7
  } from "../../consts/Theme/theme.const.js";
8
- let _theme = null;
9
- let _mode = null;
10
- let _systemPrefersDark = null;
11
- let _mediaInitDone = false;
8
+ const ORIGAM_THEME_SINGLETON_KEY = "__origamThemeSingleton__";
9
+ const _serverSingleton = {
10
+ theme: null,
11
+ mode: null,
12
+ systemPrefersDark: null,
13
+ mediaInitDone: false
14
+ };
15
+ function themeSingleton() {
16
+ if (typeof window === "undefined") return _serverSingleton;
17
+ const globalScope = globalThis;
18
+ if (!globalScope[ORIGAM_THEME_SINGLETON_KEY]) {
19
+ globalScope[ORIGAM_THEME_SINGLETON_KEY] = {
20
+ theme: null,
21
+ mode: null,
22
+ systemPrefersDark: null,
23
+ mediaInitDone: false
24
+ };
25
+ }
26
+ return globalScope[ORIGAM_THEME_SINGLETON_KEY];
27
+ }
12
28
  function ensureSystemPreference() {
13
- if (_systemPrefersDark === null) {
14
- _systemPrefersDark = ref(false);
29
+ const state = themeSingleton();
30
+ if (state.systemPrefersDark === null) {
31
+ state.systemPrefersDark = ref(false);
15
32
  }
16
- if (_mediaInitDone || typeof window === "undefined" || typeof window.matchMedia !== "function") {
17
- return _systemPrefersDark;
33
+ if (state.mediaInitDone || typeof window === "undefined" || typeof window.matchMedia !== "function") {
34
+ return state.systemPrefersDark;
18
35
  }
19
- _mediaInitDone = true;
36
+ state.mediaInitDone = true;
20
37
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
21
- _systemPrefersDark.value = mq.matches;
38
+ state.systemPrefersDark.value = mq.matches;
22
39
  mq.addEventListener?.("change", (e) => {
23
- if (_systemPrefersDark) _systemPrefersDark.value = e.matches;
40
+ if (state.systemPrefersDark) state.systemPrefersDark.value = e.matches;
24
41
  });
25
- return _systemPrefersDark;
42
+ return state.systemPrefersDark;
26
43
  }
27
44
  function readPersisted() {
28
45
  if (typeof window === "undefined") return "auto";
@@ -70,14 +87,15 @@ function applyModeToDocument(resolvedMode) {
70
87
  document.documentElement.setAttribute(MODE_ATTR, resolvedMode);
71
88
  }
72
89
  export function useTheme() {
73
- if (_theme === null) {
74
- _theme = ref(readPersisted());
90
+ const state = themeSingleton();
91
+ if (state.theme === null) {
92
+ state.theme = ref(readPersisted());
75
93
  }
76
- if (_mode === null) {
77
- _mode = ref(readPersistedModeValue());
94
+ if (state.mode === null) {
95
+ state.mode = ref(readPersistedModeValue());
78
96
  }
79
- const theme = _theme;
80
- const mode = _mode;
97
+ const theme = state.theme;
98
+ const mode = state.mode;
81
99
  const systemPrefersDark = ensureSystemPreference();
82
100
  const resolved = computed(() => {
83
101
  if (theme.value === "auto") return systemPrefersDark.value ? "dark" : "light";
@@ -140,8 +158,9 @@ export function readPersistedMode() {
140
158
  return readPersistedModeValue();
141
159
  }
142
160
  export function _resetThemeForTesting() {
143
- _theme = null;
144
- _mode = null;
145
- _systemPrefersDark = null;
146
- _mediaInitDone = false;
161
+ const state = themeSingleton();
162
+ state.theme = null;
163
+ state.mode = null;
164
+ state.systemPrefersDark = null;
165
+ state.mediaInitDone = false;
147
166
  }
@@ -14,7 +14,7 @@ import type { IBgColorProps, IColorProps, ICommonsComponentEmits, ICommonsCompon
14
14
  * cascades to descendants through normal CSS inheritance.
15
15
  */
16
16
  export interface IAppProps extends ICommonsComponentProps, IColorProps, IBgColorProps {
17
- /** Stretch the layout to the full viewport (`100vw` / `100vh`). Default `true`. */
17
+ /** Occupy at least the full viewport (`100vw` / `min-height: 100vh`) — content taller than one screen grows past it rather than clipping. Default `true`. */
18
18
  fullHeight?: boolean;
19
19
  /** IDs of layout items allowed to overlap each other (forwarded to the layout). */
20
20
  overlaps?: Array<string>;
@@ -1,5 +1,5 @@
1
- import type { IActiveProps, IBorderProps, IBtnProps, IBgColorProps, IColorProps, ICommonsComponentProps, IDensityProps, IElevationProps, IHoverProps, IMarginProps, IPaddingProps, IRoundedProps, ITagProps } from '../../interfaces';
2
- export interface IBtnGroupProps extends ITagProps, ICommonsComponentProps, IRoundedProps, IBorderProps, IDensityProps, IElevationProps, IColorProps, IBgColorProps, IMarginProps, IPaddingProps, IHoverProps, IActiveProps {
1
+ import type { IActiveProps, IBorderProps, IBtnProps, IBgColorProps, IColorProps, ICommonsComponentProps, IDensityProps, IElevationProps, IHoverProps, IMarginProps, IPaddingProps, IRoundedProps, ISizeProps, ITagProps, IVariantProps } from '../../interfaces';
2
+ export interface IBtnGroupProps extends ITagProps, ICommonsComponentProps, IRoundedProps, IBorderProps, IDensityProps, IElevationProps, IColorProps, IBgColorProps, IMarginProps, IPaddingProps, IHoverProps, IActiveProps, IVariantProps, ISizeProps {
3
3
  divided?: boolean;
4
4
  items?: Array<IBtnProps>;
5
5
  }
@@ -1,9 +1,10 @@
1
- import type { IBgColorProps, IColorProps, ICommonsComponentEmits, ICommonsComponentProps, ICommonsComponentSlots } from '../../interfaces';
1
+ import type { IBgColorProps, IBorderProps, IColorProps, ICommonsComponentEmits, ICommonsComponentProps, ICommonsComponentSlots, IElevationProps, IRoundedProps } from '../../interfaces';
2
2
  /**
3
3
  * Props for `<OrigamSwitchTrack>` — the rounded "rail" sitting behind the
4
4
  * Switch thumb. The track owns its own visual surface (background, border,
5
- * inset variant, error state) and exposes slots for content shown on the
6
- * `true` (left) and `false` (right) sides of the rail.
5
+ * inset variant, error state, rounded/elevation identity) and exposes slots
6
+ * for content shown on the `true` (left) and `false` (right) sides of the
7
+ * rail.
7
8
  *
8
9
  * Color contract — strict channel separation:
9
10
  * • `bgColor` paints the rail (the box behind the thumb).
@@ -11,8 +12,18 @@ import type { IBgColorProps, IColorProps, ICommonsComponentEmits, ICommonsCompon
11
12
  * SelectionControl (it paints the thumb via `currentColor`,
12
13
  * not the track) — exposed here so the slot content can
13
14
  * react to it (e.g. an icon inside `track.true`).
15
+ *
16
+ * `border` / `rounded` / `elevation` (props-first, lot 4 theming fix):
17
+ * previously declared on `ISwitchProps` (inherited from the Commons
18
+ * interfaces) but never consumed anywhere — `OrigamSwitch.vue` accepted
19
+ * the props without a TS error yet silently dropped them, and the track
20
+ * (the actual visible rail) didn't even have them in its own interface.
21
+ * A theme could set `'origam-switch': { border: true, rounded: 'lg' }`
22
+ * and nothing would render differently. Declared here now because the
23
+ * track is the element that owns the visual surface these props target —
24
+ * `OrigamSwitch` forwards its own values down via `filterProps`.
14
25
  */
15
- export interface ISwitchTrackProps extends ICommonsComponentProps, IColorProps, IBgColorProps {
26
+ export interface ISwitchTrackProps extends ICommonsComponentProps, IColorProps, IBgColorProps, IBorderProps, IRoundedProps, IElevationProps {
16
27
  /** Whether the switch is currently ON. Drives the `--dirty` modifier. */
17
28
  modelValue?: boolean;
18
29
  /** Validation state forwarded from the surrounding `<OrigamInput>`. */
@@ -21,8 +32,14 @@ export interface ISwitchTrackProps extends ICommonsComponentProps, IColorProps,
21
32
  disabled?: boolean;
22
33
  /** Readonly state — keeps appearance interactive but blocks input. */
23
34
  readonly?: boolean;
24
- /** Error state — overrides the rail with the danger token. */
25
- error?: boolean;
35
+ /**
36
+ * Error state — overrides the rail with the danger token. Same type
37
+ * as the Commons `IValidationProps.error` (`string | boolean` — a
38
+ * string is an error message, truthy either way) so a parent
39
+ * forwarding its own validation surface (OrigamSwitch) stays
40
+ * type-compatible. Consumed by truthiness only.
41
+ */
42
+ error?: string | boolean;
26
43
  /** Inset (Material) variant — taller, fully-rounded rail. */
27
44
  inset?: boolean;
28
45
  }
@@ -269,8 +269,7 @@ const origamLightTheme = exports.origamLightTheme = {
269
269
  },
270
270
  "origam-code": {
271
271
  tag: "figure",
272
- rounded: "lg",
273
- compact: true
272
+ rounded: "lg"
274
273
  },
275
274
  "origam-color-picker-field": {
276
275
  density: "default",
@@ -669,8 +668,7 @@ const origamDarkTheme = exports.origamDarkTheme = {
669
668
  },
670
669
  "origam-code": {
671
670
  tag: "figure",
672
- rounded: "lg",
673
- compact: true
671
+ rounded: "lg"
674
672
  },
675
673
  "origam-color-picker-field": {
676
674
  density: "default",
@@ -162,7 +162,7 @@ export const origamLightTheme = {
162
162
  "origam-checkbox": { density: "default" },
163
163
  "origam-chip": { size: "small", variant: "outlined", color: "primary", pill: true, border: true, borderColor: "var(--origam-color__action--primary---bg)" },
164
164
  "origam-clipboard": { tag: "span" },
165
- "origam-code": { tag: "figure", rounded: "lg", compact: true },
165
+ "origam-code": { tag: "figure", rounded: "lg" },
166
166
  "origam-color-picker-field": { density: "default", border: true, rounded: true },
167
167
  "origam-confirm-wrapper": { density: "default" },
168
168
  "origam-contextual-menu": { location: "right" },
@@ -312,7 +312,7 @@ export const origamDarkTheme = {
312
312
  "origam-checkbox": { density: "default" },
313
313
  "origam-chip": { size: "small", variant: "outlined", color: "primary", pill: true, border: true, borderColor: "var(--origam-color__action--primary---bg)" },
314
314
  "origam-clipboard": { tag: "span" },
315
- "origam-code": { tag: "figure", rounded: "lg", compact: true },
315
+ "origam-code": { tag: "figure", rounded: "lg" },
316
316
  "origam-color-picker-field": { density: "default", border: true, rounded: true },
317
317
  "origam-confirm-wrapper": { density: "default" },
318
318
  "origam-contextual-menu": { location: "right" },