origam 2.13.0 โ†’ 2.14.1

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 (32) hide show
  1. package/CHANGELOG.md +2012 -0
  2. package/README.md +4 -4
  3. package/dist/src/components/Avatar/OrigamAvatar.vue +14 -0
  4. package/dist/src/components/ColorPicker/OrigamColorPickerEdit.vue +7 -1
  5. package/dist/src/components/ColorPickerField/OrigamColorPickerField.vue +12 -1
  6. package/dist/src/components/DatePicker/OrigamDatePickerMonth.vue +14 -2
  7. package/dist/src/components/DatePickerField/OrigamDatePickerField.vue +14 -1
  8. package/dist/src/components/Field/OrigamField.vue +9 -7
  9. package/dist/src/components/Messages/OrigamMessages.vue +1 -0
  10. package/dist/src/components/Select/OrigamSelect.vue +16 -1
  11. package/dist/src/components/TextField/OrigamTextField.vue +1 -1
  12. package/dist/src/composables/Commons/defaults.composable.cjs +1 -1
  13. package/dist/src/composables/Commons/defaults.composable.js +1 -1
  14. package/dist/src/composables/Commons/style.composable.cjs +4 -1
  15. package/dist/src/composables/Commons/style.composable.js +4 -1
  16. package/dist/src/composables/Commons/teleport-typography.composable.cjs +38 -0
  17. package/dist/src/composables/Commons/teleport-typography.composable.d.ts +86 -0
  18. package/dist/src/composables/Commons/teleport-typography.composable.js +30 -0
  19. package/dist/src/composables/index.cjs +12 -0
  20. package/dist/src/composables/index.d.ts +1 -0
  21. package/dist/src/composables/index.js +1 -0
  22. package/dist/src/consts/Commons/rounded.const.d.ts +1 -1
  23. package/dist/src/enums/Commons/rounded.enum.cjs +12 -2
  24. package/dist/src/enums/Commons/rounded.enum.d.ts +25 -0
  25. package/dist/src/enums/Commons/rounded.enum.js +10 -0
  26. package/dist/src/themes/origam.theme.cjs +2 -2
  27. package/dist/src/themes/origam.theme.js +2 -2
  28. package/dist/src/types/Commons/rounded.type.d.ts +14 -2
  29. package/dist/src/utils/Commons/color.util.cjs +2 -2
  30. package/dist/src/utils/Commons/color.util.d.ts +24 -1
  31. package/dist/src/utils/Commons/color.util.js +2 -2
  32. package/package.json +9 -3
package/README.md CHANGED
@@ -5,7 +5,7 @@ and TypeScript types.
5
5
 
6
6
  > ๐Ÿ“– **Full documentation & interactive theme builder:**
7
7
  > [https://origam.dev](https://origam.dev) *(coming soon)* ยท
8
- > [GitHub repository](https://github.com/arnaudprioul/origam)
8
+ > [GitHub repository](https://github.com/Elyseranet/origam)
9
9
 
10
10
  ## Installation
11
11
 
@@ -75,9 +75,9 @@ Token stylesheets are exposed as dedicated entries: `origam/styles`
75
75
  ## Links
76
76
 
77
77
  - [Documentation & theme builder](https://origam.dev) *(coming soon)*
78
- - [Changelog](https://github.com/arnaudprioul/origam/blob/main/CHANGELOG.md)
79
- - [Issues](https://github.com/arnaudprioul/origam/issues)
78
+ - [Changelog](https://github.com/Elyseranet/origam/blob/main/CHANGELOG.md)
79
+ - [Issues](https://github.com/Elyseranet/origam/issues)
80
80
 
81
81
  ## License
82
82
 
83
- [MIT](https://github.com/arnaudprioul/origam/blob/main/LICENSE) ยฉ Prioul Arnaud
83
+ [MIT](https://github.com/Elyseranet/origam/blob/main/LICENSE) ยฉ Prioul Arnaud
@@ -189,6 +189,20 @@ defineExpose({
189
189
  .origam-avatar {
190
190
  $this: &;
191
191
 
192
+ // Declared on the ROOT, not only on `__wrapper`. Without it the root
193
+ // inherits the browser default โ€” `inline` for `tag="span"` โ€” and an
194
+ // inline box ignores `width`/`height`, so `size` silently did nothing:
195
+ // the avatar collapsed to its text. It only appeared to work when the
196
+ // parent was a flex container, which blockifies its children (measured:
197
+ // same component, 32x32 under `inline-flex`, 30x30 under `position:
198
+ // relative`, for a requested size of 72).
199
+ //
200
+ // `inline-flex` and not `block`: `tag="span"` exists so an avatar can sit
201
+ // in phrasing content โ€” inside a `<button>`, whose content model rejects
202
+ // block-level elements.
203
+ display: var(--origam-avatar---display, inline-flex);
204
+ vertical-align: var(--origam-avatar---vertical-align, middle);
205
+
192
206
  line-height: var(--origam-avatar---line-height);
193
207
  text-align: var(--origam-avatar---text-align);
194
208
  font-size: var(--origam-avatar---font-size);
@@ -128,7 +128,13 @@ defineExpose({
128
128
  }
129
129
 
130
130
  #{$this}__label {
131
- font-size: .75rem
131
+ // `rem` resolves against the document root, not this component's
132
+ // ancestor โ€” a plain literal here would be immune to the typography
133
+ // bridge `OrigamColorPickerField` republishes on the teleported
134
+ // surface (see `useTeleportTypography`). Generic-first read, same
135
+ // convention as `useTypography`'s rollout: the bridged var wins when
136
+ // present, the historical size is the fallback.
137
+ font-size: var(--origam-color-picker-edit__label---font-size, .75rem);
132
138
  }
133
139
  }
134
140
  }
@@ -128,7 +128,7 @@
128
128
 
129
129
  <script lang="ts" setup>
130
130
  import { OrigamColorPicker, OrigamMenu, OrigamSheet, OrigamTextField, OrigamTranslateScale } from "../../components";
131
- import { useDefaults, useLocale, useProps, useVModel, useStyle } from "../../composables";
131
+ import { useDefaults, useLocale, useProps, useTeleportTypography, useVModel, useStyle } from "../../composables";
132
132
  import { COLOR_NULL, ORIGAM_FORM_KEY } from "../../consts";
133
133
  import { BLOCK, DENSITY, DIRECTION, TEXT_FIELD_TYPE } from "../../enums";
134
134
  import { forwardRefs, HSVtoCSS, matchesSelector } from "../../utils";
@@ -295,13 +295,24 @@ const form = inject(ORIGAM_FORM_KEY, null);
295
295
  const menuDisabled = computed(() => {
296
296
  return props.readonly || form?.isReadonly.value;
297
297
  });
298
+ const { typographyStyles: menuTypographyStyles } = useTeleportTypography(origamTextFieldRef, menu, (fontSize) => ({
299
+ "--origam-picker-title---font-size": fontSize,
300
+ "--origam-color-picker-edit__label---font-size": fontSize
301
+ }));
298
302
  const menuProps = computed(() => {
303
+ const consumerContentProps = props.menuProps?.contentProps ?? {};
299
304
  return {
300
305
  ...props.menuProps,
301
306
  activatorProps: {
302
307
  ...props.menuProps?.activatorProps || {},
303
308
  "aria-haspopup": "colorpickerbox"
304
309
  // Set aria-haspopup to 'listbox'
310
+ },
311
+ contentProps: {
312
+ ...consumerContentProps,
313
+ // The consumer's own style is listed last so it still wins โ€”
314
+ // the bridge is a default, not a lock.
315
+ style: [menuTypographyStyles.value, consumerContentProps.style]
305
316
  }
306
317
  };
307
318
  });
@@ -269,7 +269,12 @@ defineExpose({
269
269
  display: grid;
270
270
  grid-template-rows: repeat(7, 1fr);
271
271
  column-gap: 4px;
272
- font-size: .85rem;
272
+ // `rem` resolves against the document root, not this component's
273
+ // ancestor โ€” a plain literal here would be immune to the typography
274
+ // bridge `OrigamDatePickerField` republishes on the teleported
275
+ // surface (see `useTeleportTypography`). Generic-first read, same
276
+ // convention as `useTypography`'s rollout.
277
+ font-size: var(--origam-date-picker-month__weeks---font-size, .85rem);
273
278
 
274
279
  + #{$this}__days {
275
280
  grid-row-gap: 0;
@@ -277,7 +282,7 @@ defineExpose({
277
282
  }
278
283
 
279
284
  &__weekday {
280
- font-size: .85rem;
285
+ font-size: var(--origam-date-picker-month__weekday---font-size, .85rem);
281
286
  }
282
287
 
283
288
  &__days {
@@ -300,6 +305,13 @@ defineExpose({
300
305
  :deep(.origam-btn) {
301
306
  --origam-btn---height: 24px;
302
307
  --origam-btn---size: .85rem;
308
+ // `OrigamBtn`'s own `--size-*` modifier sets `--origam-btn---font-size`
309
+ // directly on this same element (its size prop is unset here, so it's
310
+ // the default rung) โ€” an inherited custom property from an ancestor
311
+ // loses to that local declaration. A plain `font-size` read here, at
312
+ // equal locality, is what actually wins; same rem-trap as `&__weeks` /
313
+ // `&__weekday` above, bridged token first, historical size as fallback.
314
+ font-size: var(--origam-date-picker-month__day---font-size, .85rem);
303
315
  z-index: 1;
304
316
  }
305
317
 
@@ -180,7 +180,7 @@ import {
180
180
  OrigamTextField,
181
181
  OrigamTranslateScale
182
182
  } from "../../components";
183
- import { useDate, useDefaults, useLocale, useProps, useTextColor, useVModel, useStyle } from "../../composables";
183
+ import { useDate, useDefaults, useLocale, useProps, useTeleportTypography, useTextColor, useVModel, useStyle } from "../../composables";
184
184
  import { ORIGAM_FORM_KEY } from "../../consts";
185
185
  import { BLOCK, DENSITY, DIRECTION, KEYBOARD_VALUES, MDI_ICONS, TEXT_FIELD_TYPE } from "../../enums";
186
186
  import { forwardRefs, isEmpty, matchesSelector, wrapInArray } from "../../utils";
@@ -370,13 +370,26 @@ const form = inject(ORIGAM_FORM_KEY, null);
370
370
  const menuDisabled = computed(() => {
371
371
  return props.readonly || form?.isReadonly.value;
372
372
  });
373
+ const { typographyStyles: menuTypographyStyles } = useTeleportTypography(origamTextFieldRef, menu, (fontSize) => ({
374
+ "--origam-picker-title---font-size": fontSize,
375
+ "--origam-date-picker-month__weekday---font-size": fontSize,
376
+ "--origam-date-picker-month__weeks---font-size": fontSize,
377
+ "--origam-date-picker-month__day---font-size": fontSize
378
+ }));
373
379
  const menuProps = computed(() => {
380
+ const consumerContentProps = props.menuProps?.contentProps ?? {};
374
381
  return {
375
382
  ...props.menuProps,
376
383
  activatorProps: {
377
384
  ...props.menuProps?.activatorProps || {},
378
385
  "aria-haspopup": "datepickerbox"
379
386
  // Set aria-haspopup to 'listbox'
387
+ },
388
+ contentProps: {
389
+ ...consumerContentProps,
390
+ // The consumer's own style is listed last so it still wins โ€”
391
+ // the bridge is a default, not a lock.
392
+ style: [menuTypographyStyles.value, consumerContentProps.style]
380
393
  }
381
394
  };
382
395
  });
@@ -783,15 +783,17 @@ defineExpose({
783
783
  &--prepended {
784
784
  --origam-field---padding-start: 6px;
785
785
 
786
- // A prepend-inner (icon / swatch) already fills the left corner, so
787
- // opt out of the corner-clearing floor: keep the inline padding and
788
- // the start outline leg at the raw padding-start (widening them would
789
- // draw the outline over the prepend content).
786
+ // Le CONTENU se rapproche du bord (l'icone/swatch remplit le coin),
787
+ // donc on retire le plancher de degagement sur le padding.
790
788
  padding-inline: var(--origam-field---padding-start) var(--origam-field---padding-end);
791
789
 
792
- #{$this}__outline--start {
793
- flex-basis: var(--origam-field---padding-start);
794
- }
790
+ // MAIS on ne touche PAS a la largeur de la patte d'outline : ce
791
+ // segment PORTE le rayon du coin gauche, et CSS reduit proportionnellement
792
+ // un `border-radius` qui depasse la boite qui le declare (une patte de
793
+ // 6px ne peut pas rendre un rayon de 12px+ : le coin sort plat). Le
794
+ // couplage n'avait pas lieu d'etre : `__outlines` est `position: absolute`
795
+ // + `pointer-events: none`, une couche decorative qui ne deplace aucun
796
+ // contenu โ€” l'elargir ne dessine rien par-dessus le prepend.
795
797
  }
796
798
 
797
799
  &--appended {
@@ -5,6 +5,7 @@
5
5
  >
6
6
  <component
7
7
  :is="props.tag"
8
+ :id="props.id"
8
9
  :class="messagesClasses"
9
10
  :style="[messagesStyles, rootTypographyStyles]"
10
11
  aria-live="polite"
@@ -298,6 +298,7 @@ import {
298
298
  useProps,
299
299
  useScrolling,
300
300
  useStyle,
301
+ useTeleportTypography,
301
302
  useTextColor,
302
303
  useVModel
303
304
  } from "../../composables";
@@ -541,9 +542,23 @@ const displayItems = computed(() => {
541
542
  const menuDisabled = computed(() => {
542
543
  return props.hideNoData && !displayItems.value.length || props.readonly || form?.isReadonly.value;
543
544
  });
545
+ const { typographyStyles: menuTypographyStyles } = useTeleportTypography(origamTextFieldRef, menu, (fontSize) => ({
546
+ "--origam-list-item__title---font-size": fontSize,
547
+ // Kept proportional to the title rather than pinned, so the pair
548
+ // keeps its relationship at any scale.
549
+ "--origam-list-item__subtitle---font-size": `calc(${fontSize} * 0.875)`
550
+ }));
544
551
  const menuProps = computed(() => {
552
+ const consumerProps = props.menuProps ?? {};
553
+ const consumerContentProps = consumerProps.contentProps ?? {};
545
554
  return {
546
- ...props.menuProps
555
+ ...consumerProps,
556
+ contentProps: {
557
+ ...consumerContentProps,
558
+ // The consumer's own style is listed last so it still wins โ€”
559
+ // the bridge is a default, not a lock.
560
+ style: [menuTypographyStyles.value, consumerContentProps.style]
561
+ }
547
562
  };
548
563
  });
549
564
  const comboboxAriaAttrs = computed(() => {
@@ -483,7 +483,7 @@ const enrichedRules = computed(() => {
483
483
  });
484
484
  const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
485
485
  const inputProps = computed(() => {
486
- return origamInputRef.value?.filterProps(props, ["modelValue", "class", "style", "id", "focused"]);
486
+ return origamInputRef.value?.filterProps(props, ["modelValue", "class", "style", "focused"]);
487
487
  });
488
488
  const fieldProps = computed(() => {
489
489
  return origamFieldRef.value?.filterProps(props, ["class", "id", "active", "dirty", "disabled", "focused", "error", "style"]);
@@ -18,7 +18,7 @@ function usePassedProps(_props, instanceLabel = "usePassedProps") {
18
18
  return key => {
19
19
  const vnodeProps = vm.vnode.props || {};
20
20
  for (const k in vnodeProps) {
21
- if (k === key || camelize(k) === key) return true;
21
+ if (k === key || camelize(k) === key) return vnodeProps[k] !== void 0;
22
22
  }
23
23
  return false;
24
24
  };
@@ -9,7 +9,7 @@ export function usePassedProps(_props, instanceLabel = "usePassedProps") {
9
9
  return (key) => {
10
10
  const vnodeProps = vm.vnode.props || {};
11
11
  for (const k in vnodeProps) {
12
- if (k === key || camelize(k) === key) return true;
12
+ if (k === key || camelize(k) === key) return vnodeProps[k] !== void 0;
13
13
  }
14
14
  return false;
15
15
  };
@@ -63,7 +63,10 @@ function toDeclarations(value) {
63
63
  }
64
64
  function useStyle(styles, uniq = void 0, name = (0, _utils.getCurrentInstanceName)()) {
65
65
  const fallbackId = `${name}-${(0, _utils.getUid)()}`;
66
- const id = (0, _vue.computed)(() => (0, _vue.toValue)(uniq) || fallbackId);
66
+ const id = (0, _vue.computed)(() => {
67
+ const requested = (0, _vue.toValue)(uniq);
68
+ return typeof requested === "string" && requested.length > 0 ? requested : fallbackId;
69
+ });
67
70
  const customCss = (0, _vue.computed)(() => {
68
71
  const stylesArray = toDeclarations(styles.value);
69
72
  return `#${(0, _utils.escapeCssIdent)(id.value)} {${stylesArray.join(";")}}`;
@@ -65,7 +65,10 @@ function toDeclarations(value) {
65
65
  }
66
66
  export function useStyle(styles, uniq = void 0, name = getCurrentInstanceName()) {
67
67
  const fallbackId = `${name}-${getUid()}`;
68
- const id = computed(() => toValue(uniq) || fallbackId);
68
+ const id = computed(() => {
69
+ const requested = toValue(uniq);
70
+ return typeof requested === "string" && requested.length > 0 ? requested : fallbackId;
71
+ });
69
72
  const customCss = computed(() => {
70
73
  const stylesArray = toDeclarations(styles.value);
71
74
  return `#${escapeCssIdent(id.value)} {${stylesArray.join(";")}}`;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useTeleportTypography = useTeleportTypography;
7
+ var _vue = require("vue");
8
+ function useTeleportTypography(fieldRef, isOpen, extraVars, measureSelector = ".origam-field", neutralFontSize = "16px") {
9
+ const typographyStyles = (0, _vue.ref)({});
10
+ const fieldElement = () => {
11
+ const root = fieldRef.value?.$el;
12
+ if (!root || typeof root.querySelector !== "function") return void 0;
13
+ return root.querySelector(measureSelector) ?? root;
14
+ };
15
+ const sync = () => {
16
+ const el = fieldElement();
17
+ if (!el || typeof window === "undefined") return;
18
+ const styles = window.getComputedStyle(el);
19
+ const fontSize = styles.fontSize;
20
+ if (!fontSize) return;
21
+ if (fontSize === neutralFontSize) {
22
+ typographyStyles.value = {};
23
+ return;
24
+ }
25
+ typographyStyles.value = {
26
+ "font-family": styles.fontFamily,
27
+ "font-size": fontSize,
28
+ "letter-spacing": styles.letterSpacing,
29
+ ...extraVars(fontSize)
30
+ };
31
+ };
32
+ (0, _vue.watch)(isOpen, open => {
33
+ if (open) (0, _vue.nextTick)(sync);
34
+ });
35
+ return {
36
+ typographyStyles
37
+ };
38
+ }
@@ -0,0 +1,86 @@
1
+ import type { Ref } from 'vue';
2
+ /**
3
+ * useTeleportTypography โ€” bridges the field's REAL typography across a
4
+ * teleported surface (menu, picker, โ€ฆ).
5
+ *
6
+ * @description
7
+ * Floating surfaces (`OrigamMenu` and everything built on it โ€” Select's
8
+ * option list, ColorPickerField's channel editor, DatePickerField's
9
+ * calendar) are teleported out of the field's DOM subtree, to escape
10
+ * `overflow` and stacking contexts. A CSS rule the consuming application
11
+ * writes against the field โ€” `.my-field * { font-size: 13px }`, a compact
12
+ * form theme, a scaled container โ€” therefore never reaches the popup: the
13
+ * selector simply does not match nodes outside the field's subtree.
14
+ *
15
+ * Re-inheriting `font-size` on the teleported root is NOT enough on its
16
+ * own, either. Descendant text that sizes itself with a `rem`-based token
17
+ * (`var(--origam-list-item__title---font-size, 1rem)`,
18
+ * `var(--origam-picker-title---font-size, .75rem)`, โ€ฆ) resolves `rem`
19
+ * against the DOCUMENT ROOT, not the inherited value โ€” it would keep the
20
+ * root size whatever the teleported ancestor inherits.
21
+ *
22
+ * So this composable measures the typography that ACTUALLY WON on the
23
+ * field when the surface opens (`getComputedStyle`, not the props โ€” the
24
+ * props can't see a consumer's own stylesheet) and hands back a plain
25
+ * style object the caller republishes on the teleported content root as
26
+ * both generic CSS (`font-family` / `font-size` / `letter-spacing`, for
27
+ * whatever inherits normally) AND the specific component tokens the
28
+ * surface's own `rem`-sized text reads (via `extraVars`), so the two
29
+ * layers of the bug are closed together. Originates from `OrigamSelect`
30
+ * (commit `8354407c`) โ€” extracted here so `OrigamColorPickerField` /
31
+ * `OrigamDatePickerField` don't reimplement the same measurement.
32
+ *
33
+ * Measured on `.origam-field` (NOT the raw `<input>`), which is the one
34
+ * element every `<origam-text-field>`-based field renders with a plain,
35
+ * unconditional `font-size: 16px` (no prop/token influences it โ€” see
36
+ * `OrigamField`'s own SCSS). The raw `<input>` is NOT a safe measurement
37
+ * point: on `OrigamColorPickerField` / `OrigamDatePickerField` it is
38
+ * deliberately taken out of flow and carries none of `OrigamInput`'s
39
+ * classes, so it renders at the BROWSER's own default control font
40
+ * (13.3333px in Chrome) rather than the design system's โ€” a value with
41
+ * nothing to do with the field's real typography.
42
+ *
43
+ * That same "16px, unconditionally" fact is also what keeps this bridge a
44
+ * true no-op absent a consumer override: `neutralFontSize` (default
45
+ * `'16px'`) is the value `.origam-field` would show with zero consuming-app
46
+ * CSS involved. When the measured size still equals it, nothing diverges โ€”
47
+ * `typographyStyles` stays empty and every surface keeps its OWN historical
48
+ * default (`.75rem` list-item text, `.85rem` calendar cells, โ€ฆ), instead of
49
+ * being forced to 16px on every open. Only an ACTUAL divergence (a
50
+ * consumer's stylesheet, a different field wrapper with its own baseline)
51
+ * republishes the tokens.
52
+ *
53
+ * @param fieldRef ref to the field sub-component (e.g. the wrapped
54
+ * `<origam-text-field>`). Its `$el` is the DOM root the
55
+ * typography is measured FROM.
56
+ * @param isOpen ref toggled when the teleported surface opens; the
57
+ * measurement re-runs on every open (the consumer's CSS
58
+ * can change between opens โ€” a live theme switch, a
59
+ * responsive breakpoint, โ€ฆ).
60
+ * @param extraVars given the resolved `font-size`, returns the extra
61
+ * `{ '--origam-โ€ฆ---font-size': value }` entries for the
62
+ * specific tokens the surface's own `rem`-sized text
63
+ * reads. Read the surface's SCSS before adding one โ€”
64
+ * republishing a var nothing consumes is a no-op.
65
+ * @param measureSelector selector for the element the typography is read
66
+ * from, resolved within `fieldRef`'s root (defaults to
67
+ * `'.origam-field'`). Falls back to the root itself when
68
+ * no match is found.
69
+ * @param neutralFontSize the `measureSelector` element's OWN unstyled
70
+ * `font-size` (defaults to `'16px'`, `.origam-field`'s
71
+ * literal default). When the measured value still equals
72
+ * this, the bridge is a no-op for this open โ€” see above.
73
+ *
74
+ * @example
75
+ * const { typographyStyles } = useTeleportTypography(origamTextFieldRef, menu, (fontSize) => ({
76
+ * '--origam-list-item__title---font-size': fontSize,
77
+ * '--origam-list-item__subtitle---font-size': `calc(${ fontSize } * 0.875)`
78
+ * }))
79
+ * // โ€ฆ
80
+ * contentProps: { style: [typographyStyles.value, consumerContentProps.style] }
81
+ */
82
+ export declare function useTeleportTypography(fieldRef: Ref<{
83
+ $el?: HTMLElement;
84
+ } | undefined>, isOpen: Ref<boolean>, extraVars: (fontSize: string) => Record<string, string>, measureSelector?: string, neutralFontSize?: string): {
85
+ typographyStyles: Ref<Record<string, string>, Record<string, string>>;
86
+ };
@@ -0,0 +1,30 @@
1
+ import { nextTick, ref, watch } from "vue";
2
+ export function useTeleportTypography(fieldRef, isOpen, extraVars, measureSelector = ".origam-field", neutralFontSize = "16px") {
3
+ const typographyStyles = ref({});
4
+ const fieldElement = () => {
5
+ const root = fieldRef.value?.$el;
6
+ if (!root || typeof root.querySelector !== "function") return void 0;
7
+ return root.querySelector(measureSelector) ?? root;
8
+ };
9
+ const sync = () => {
10
+ const el = fieldElement();
11
+ if (!el || typeof window === "undefined") return;
12
+ const styles = window.getComputedStyle(el);
13
+ const fontSize = styles.fontSize;
14
+ if (!fontSize) return;
15
+ if (fontSize === neutralFontSize) {
16
+ typographyStyles.value = {};
17
+ return;
18
+ }
19
+ typographyStyles.value = {
20
+ "font-family": styles.fontFamily,
21
+ "font-size": fontSize,
22
+ "letter-spacing": styles.letterSpacing,
23
+ ...extraVars(fontSize)
24
+ };
25
+ };
26
+ watch(isOpen, (open) => {
27
+ if (open) nextTick(sync);
28
+ });
29
+ return { typographyStyles };
30
+ }
@@ -588,6 +588,18 @@ Object.keys(_teleport).forEach(function (key) {
588
588
  }
589
589
  });
590
590
  });
591
+ var _teleportTypography = require("./Commons/teleport-typography.composable.cjs");
592
+ Object.keys(_teleportTypography).forEach(function (key) {
593
+ if (key === "default" || key === "__esModule") return;
594
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
595
+ if (key in exports && exports[key] === _teleportTypography[key]) return;
596
+ Object.defineProperty(exports, key, {
597
+ enumerable: true,
598
+ get: function () {
599
+ return _teleportTypography[key];
600
+ }
601
+ });
602
+ });
591
603
  var _hydration = require("./Commons/hydration.composable.cjs");
592
604
  Object.keys(_hydration).forEach(function (key) {
593
605
  if (key === "default" || key === "__esModule") return;
@@ -46,6 +46,7 @@ export * from './Commons/margin.composable';
46
46
  export * from './Commons/lazy.composable';
47
47
  export * from './Commons/items.composable';
48
48
  export * from './Commons/teleport.composable';
49
+ export * from './Commons/teleport-typography.composable';
49
50
  export * from './Commons/hydration.composable';
50
51
  export * from './Commons/stack.composable';
51
52
  export * from './Commons/activator.composable';
@@ -46,6 +46,7 @@ export * from "./Commons/margin.composable.js";
46
46
  export * from "./Commons/lazy.composable.js";
47
47
  export * from "./Commons/items.composable.js";
48
48
  export * from "./Commons/teleport.composable.js";
49
+ export * from "./Commons/teleport-typography.composable.js";
49
50
  export * from "./Commons/hydration.composable.js";
50
51
  export * from "./Commons/stack.composable.js";
51
52
  export * from "./Commons/activator.composable.js";
@@ -35,4 +35,4 @@ export declare const PREDEFINED_ROUNDED: Array<TRounded>;
35
35
  * backward compatibility and slated for removal in a future major. Use
36
36
  * `PREDEFINED_ROUNDED`.
37
37
  */
38
- export declare const PREDIFINED_ROUNDED: ("default" | "x-small" | "small" | "medium" | "large" | "x-large" | "shaped" | "shaped-invert")[];
38
+ export declare const PREDIFINED_ROUNDED: TRounded[];
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.ROUNDED = void 0;
6
+ exports.ROUNDED_TOKEN = exports.ROUNDED = void 0;
7
7
  var ROUNDED = exports.ROUNDED = /* @__PURE__ */(ROUNDED2 => {
8
8
  ROUNDED2["X_SMALL"] = "x-small";
9
9
  ROUNDED2["SMALL"] = "small";
@@ -14,4 +14,14 @@ var ROUNDED = exports.ROUNDED = /* @__PURE__ */(ROUNDED2 => {
14
14
  ROUNDED2["SHAPED"] = "shaped";
15
15
  ROUNDED2["SHAPED_INVERT"] = "shaped-invert";
16
16
  return ROUNDED2;
17
- })(ROUNDED || {});
17
+ })(ROUNDED || {});
18
+ var ROUNDED_TOKEN = exports.ROUNDED_TOKEN = /* @__PURE__ */(ROUNDED_TOKEN2 => {
19
+ ROUNDED_TOKEN2["NONE"] = "none";
20
+ ROUNDED_TOKEN2["XS"] = "xs";
21
+ ROUNDED_TOKEN2["SM"] = "sm";
22
+ ROUNDED_TOKEN2["MD"] = "md";
23
+ ROUNDED_TOKEN2["LG"] = "lg";
24
+ ROUNDED_TOKEN2["XL"] = "xl";
25
+ ROUNDED_TOKEN2["FULL"] = "full";
26
+ return ROUNDED_TOKEN2;
27
+ })(ROUNDED_TOKEN || {});
@@ -15,3 +15,28 @@ export declare enum ROUNDED {
15
15
  SHAPED = "shaped",
16
16
  SHAPED_INVERT = "shaped-invert"
17
17
  }
18
+ /**
19
+ * The token-scale rungs, resolved by `useRounded` to the generated utility
20
+ * classes (`.origam--rounded-full` โ†’ `var(--origam-radius---full)`).
21
+ *
22
+ * They were always accepted at runtime โ€” the brand themes have shipped
23
+ * `rounded: 'md'` / `'lg'` / `'none'` for a while โ€” but `TRounded` only
24
+ * described the component scale above, so TypeScript rejected them and they
25
+ * were invisible to autocompletion. `FULL` in particular is the only way to
26
+ * obtain a circle, which made a round avatar undiscoverable: none of the
27
+ * component-scale names produces one.
28
+ *
29
+ * Declared as a separate enum rather than merged into `ROUNDED` because the
30
+ * two scales are different things โ€” `ROUNDED` names an intent (`shaped`),
31
+ * this one names a radius rung โ€” and merging them would suggest
32
+ * `x-small` and `xs` are interchangeable. They are not.
33
+ */
34
+ export declare enum ROUNDED_TOKEN {
35
+ NONE = "none",
36
+ XS = "xs",
37
+ SM = "sm",
38
+ MD = "md",
39
+ LG = "lg",
40
+ XL = "xl",
41
+ FULL = "full"
42
+ }
@@ -9,3 +9,13 @@ export var ROUNDED = /* @__PURE__ */ ((ROUNDED2) => {
9
9
  ROUNDED2["SHAPED_INVERT"] = "shaped-invert";
10
10
  return ROUNDED2;
11
11
  })(ROUNDED || {});
12
+ export var ROUNDED_TOKEN = /* @__PURE__ */ ((ROUNDED_TOKEN2) => {
13
+ ROUNDED_TOKEN2["NONE"] = "none";
14
+ ROUNDED_TOKEN2["XS"] = "xs";
15
+ ROUNDED_TOKEN2["SM"] = "sm";
16
+ ROUNDED_TOKEN2["MD"] = "md";
17
+ ROUNDED_TOKEN2["LG"] = "lg";
18
+ ROUNDED_TOKEN2["XL"] = "xl";
19
+ ROUNDED_TOKEN2["FULL"] = "full";
20
+ return ROUNDED_TOKEN2;
21
+ })(ROUNDED_TOKEN || {});
@@ -210,7 +210,7 @@ const origamLightTheme = exports.origamLightTheme = {
210
210
  "origam-avatar": {
211
211
  tag: "div",
212
212
  size: "default",
213
- rounded: "lg",
213
+ rounded: "full",
214
214
  color: "primary"
215
215
  },
216
216
  "origam-badge": {
@@ -609,7 +609,7 @@ const origamDarkTheme = exports.origamDarkTheme = {
609
609
  "origam-avatar": {
610
610
  tag: "div",
611
611
  size: "default",
612
- rounded: "lg",
612
+ rounded: "full",
613
613
  color: "primary"
614
614
  },
615
615
  "origam-badge": {
@@ -149,7 +149,7 @@ export const origamLightTheme = {
149
149
  components: {
150
150
  "origam-alert": { tag: "div", density: "default" },
151
151
  "origam-audio": { tag: "article", variant: "expanded", position: "relative" },
152
- "origam-avatar": { tag: "div", size: "default", rounded: "lg", color: "primary" },
152
+ "origam-avatar": { tag: "div", size: "default", rounded: "full", color: "primary" },
153
153
  "origam-badge": { tag: "div", location: "top right" },
154
154
  "origam-blockquote": { tag: "blockquote", variant: "default" },
155
155
  "origam-bottom-nav": { tag: "nav", position: "start" },
@@ -299,7 +299,7 @@ export const origamDarkTheme = {
299
299
  components: {
300
300
  "origam-alert": { tag: "div", density: "default" },
301
301
  "origam-audio": { tag: "article", variant: "expanded", position: "relative" },
302
- "origam-avatar": { tag: "div", size: "default", rounded: "lg", color: "primary" },
302
+ "origam-avatar": { tag: "div", size: "default", rounded: "full", color: "primary" },
303
303
  "origam-badge": { tag: "div", location: "top right" },
304
304
  "origam-blockquote": { tag: "blockquote", variant: "default" },
305
305
  "origam-bottom-nav": { tag: "nav", position: "start" },
@@ -1,2 +1,14 @@
1
- import { ROUNDED } from '../../enums';
2
- export type TRounded = `${ROUNDED}`;
1
+ import { ROUNDED, ROUNDED_TOKEN } from '../../enums';
2
+ /**
3
+ * Every value the `rounded` prop accepts.
4
+ *
5
+ * Two scales, deliberately kept distinct (see `rounded.enum.ts`):
6
+ * - `ROUNDED` โ€” the component scale, naming an intent (`shaped`, `large`);
7
+ * - `ROUNDED_TOKEN` โ€” the radius rungs (`md`, `full`), resolved to the
8
+ * generated utility classes.
9
+ *
10
+ * The token scale was already honoured at runtime but was missing from this
11
+ * type, so `rounded="full"` โ€” the only way to get a circle โ€” failed to
12
+ * type-check and never surfaced in autocompletion.
13
+ */
14
+ export type TRounded = `${ROUNDED}` | `${ROUNDED_TOKEN}`;
@@ -45,10 +45,10 @@ var _consts = require("../../consts/index.cjs");
45
45
  var _commons = require("./commons.util.cjs");
46
46
  var _console = require("./console.util.cjs");
47
47
  function isCssColor(color) {
48
- return !!color && (/^(#|var\(--|(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\()/i.test(color) || _consts.CSS_NAMED_COLORS.has(color.toLowerCase()));
48
+ return !!color && (/^(#|var\(--|(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color-mix|color)\()/i.test(color) || _consts.CSS_NAMED_COLORS.has(color.toLowerCase()));
49
49
  }
50
50
  function isParsableColor(color) {
51
- return isCssColor(color) && !/^((rgb|hsl)a?\()?var\(--/.test(color);
51
+ return isCssColor(color) && !/^((rgb|hsl)a?\()?var\(--/.test(color) && !/^color-mix\(/i.test(color);
52
52
  }
53
53
  function parseColor(color) {
54
54
  if (typeof color === "number") {