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.
- package/CHANGELOG.md +2012 -0
- package/README.md +4 -4
- package/dist/src/components/Avatar/OrigamAvatar.vue +14 -0
- package/dist/src/components/ColorPicker/OrigamColorPickerEdit.vue +7 -1
- package/dist/src/components/ColorPickerField/OrigamColorPickerField.vue +12 -1
- package/dist/src/components/DatePicker/OrigamDatePickerMonth.vue +14 -2
- package/dist/src/components/DatePickerField/OrigamDatePickerField.vue +14 -1
- package/dist/src/components/Field/OrigamField.vue +9 -7
- package/dist/src/components/Messages/OrigamMessages.vue +1 -0
- package/dist/src/components/Select/OrigamSelect.vue +16 -1
- package/dist/src/components/TextField/OrigamTextField.vue +1 -1
- package/dist/src/composables/Commons/defaults.composable.cjs +1 -1
- package/dist/src/composables/Commons/defaults.composable.js +1 -1
- package/dist/src/composables/Commons/style.composable.cjs +4 -1
- package/dist/src/composables/Commons/style.composable.js +4 -1
- package/dist/src/composables/Commons/teleport-typography.composable.cjs +38 -0
- package/dist/src/composables/Commons/teleport-typography.composable.d.ts +86 -0
- package/dist/src/composables/Commons/teleport-typography.composable.js +30 -0
- package/dist/src/composables/index.cjs +12 -0
- package/dist/src/composables/index.d.ts +1 -0
- package/dist/src/composables/index.js +1 -0
- package/dist/src/consts/Commons/rounded.const.d.ts +1 -1
- package/dist/src/enums/Commons/rounded.enum.cjs +12 -2
- package/dist/src/enums/Commons/rounded.enum.d.ts +25 -0
- package/dist/src/enums/Commons/rounded.enum.js +10 -0
- package/dist/src/themes/origam.theme.cjs +2 -2
- package/dist/src/themes/origam.theme.js +2 -2
- package/dist/src/types/Commons/rounded.type.d.ts +14 -2
- package/dist/src/utils/Commons/color.util.cjs +2 -2
- package/dist/src/utils/Commons/color.util.d.ts +24 -1
- package/dist/src/utils/Commons/color.util.js +2 -2
- 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/
|
|
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/
|
|
79
|
-
- [Issues](https://github.com/
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
787
|
-
//
|
|
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
|
-
|
|
793
|
-
|
|
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 {
|
|
@@ -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
|
-
...
|
|
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", "
|
|
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
|
|
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
|
|
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)(() =>
|
|
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(() =>
|
|
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:
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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
|
-
|
|
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") {
|