origam 2.8.1 → 2.10.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/dist/src/assets/css/main.css +1 -1
- package/dist/src/assets/css/tokens/dark.css +38 -4
- package/dist/src/assets/css/tokens/light.css +19 -2
- package/dist/src/assets/scss/tokens/_dark.scss +19 -2
- package/dist/src/assets/scss/tokens/_light.scss +19 -2
- package/dist/src/components/Alert/OrigamAlert.vue +4 -2
- package/dist/src/components/App/OrigamApp.vue +7 -6
- package/dist/src/components/Avatar/OrigamAvatarGroup.vue +31 -12
- package/dist/src/components/Btn/OrigamBtn.vue +11 -2
- package/dist/src/components/Btn/OrigamBtnGroup.vue +204 -22
- package/dist/src/components/Btn/OrigamBtnToggle.vue +5 -1
- package/dist/src/components/Card/OrigamCard.vue +5 -2
- package/dist/src/components/Checkbox/OrigamCheckbox.vue +3 -1
- package/dist/src/components/Chip/OrigamChip.vue +2 -0
- package/dist/src/components/Code/OrigamCode.vue +4 -2
- package/dist/src/components/ColorPicker/OrigamColorPickerPreview.vue +1 -1
- package/dist/src/components/ColorPickerField/OrigamColorPickerField.vue +52 -2
- package/dist/src/components/DatePickerField/OrigamDatePickerField.vue +32 -2
- package/dist/src/components/Dialog/OrigamDialog.vue +1 -1
- package/dist/src/components/Field/OrigamField.vue +39 -3
- package/dist/src/components/Layout/OrigamLayout.vue +10 -1
- package/dist/src/components/Menu/OrigamMenu.vue +3 -1
- package/dist/src/components/NumberField/OrigamNumberField.vue +3 -2
- package/dist/src/components/Overlay/OrigamOverlayScrim.vue +2 -0
- package/dist/src/components/Radio/OrigamRadio.vue +3 -1
- package/dist/src/components/Select/OrigamSelect.vue +3 -1
- package/dist/src/components/SelectionControl/OrigamSelectionControl.vue +2 -0
- package/dist/src/components/SliderField/OrigamSliderField.vue +26 -13
- package/dist/src/components/Snackbar/OrigamSnackbar.vue +3 -1
- package/dist/src/components/Snackbar/OrigamSnackbarItem.vue +2 -0
- package/dist/src/components/Switch/OrigamSwitch.vue +42 -1
- package/dist/src/components/Switch/OrigamSwitchTrack.vue +35 -2
- package/dist/src/components/Table/OrigamTable.vue +4 -2
- package/dist/src/components/Tabs/OrigamTabs.vue +3 -1
- package/dist/src/components/Tooltip/OrigamTooltip.vue +2 -0
- package/dist/src/composables/Commons/defaults.composable.cjs +10 -6
- package/dist/src/composables/Commons/defaults.composable.d.ts +30 -0
- package/dist/src/composables/Commons/defaults.composable.js +9 -6
- package/dist/src/composables/Theme/theme.composable.cjs +49 -30
- package/dist/src/composables/Theme/theme.composable.js +41 -22
- package/dist/src/interfaces/App/app.interface.d.ts +1 -1
- package/dist/src/interfaces/Btn/btn-group.interface.d.ts +2 -2
- package/dist/src/interfaces/Switch/switch-track.interface.d.ts +23 -6
- package/dist/src/themes/origam.theme.cjs +2 -4
- package/dist/src/themes/origam.theme.js +2 -2
- package/dist/src/types/tokens.type.d.ts +1 -1
- package/dist/src/utils/Commons/commons.util.cjs +10 -0
- package/dist/src/utils/Commons/commons.util.d.ts +18 -0
- package/dist/src/utils/Commons/commons.util.js +9 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
|
-
:is="tag"
|
|
3
|
+
:is="props.tag"
|
|
4
4
|
:class="tableClasses"
|
|
5
5
|
:style="tableStyles"
|
|
6
6
|
@mouseenter="onMouseenter"
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
<script lang="ts" setup>
|
|
32
32
|
import { computed, StyleValue, useSlots } from "vue";
|
|
33
33
|
import {
|
|
34
|
+
useDefaults,
|
|
34
35
|
useDensity,
|
|
35
36
|
useDimension,
|
|
36
37
|
useHover,
|
|
@@ -40,7 +41,7 @@ import {
|
|
|
40
41
|
useTypography
|
|
41
42
|
} from "../../composables";
|
|
42
43
|
import { DENSITY } from "../../enums";
|
|
43
|
-
const
|
|
44
|
+
const _props = defineProps({
|
|
44
45
|
fixedHeader: { type: Boolean, required: false },
|
|
45
46
|
fixedFooter: { type: Boolean, required: false },
|
|
46
47
|
caption: { type: String, required: false },
|
|
@@ -97,6 +98,7 @@ const props = defineProps({
|
|
|
97
98
|
lineHeight: { type: String, required: false },
|
|
98
99
|
letterSpacing: { type: String, required: false }
|
|
99
100
|
});
|
|
101
|
+
const props = useDefaults(_props);
|
|
100
102
|
const { filterProps } = useProps(props);
|
|
101
103
|
const slots = useSlots();
|
|
102
104
|
const { densityClasses } = useDensity(props);
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
import { computed, ref, StyleValue } from "vue";
|
|
23
23
|
import { OrigamDefaultsProvider } from "../../components";
|
|
24
24
|
import {
|
|
25
|
+
useDefaults,
|
|
25
26
|
useDensity,
|
|
26
27
|
useGroup,
|
|
27
28
|
useProps,
|
|
@@ -30,7 +31,7 @@ import {
|
|
|
30
31
|
} from "../../composables";
|
|
31
32
|
import { ORIGAM_TABS_KEY } from "../../consts";
|
|
32
33
|
import { DENSITY, DIRECTION, TAB_VARIANT } from "../../enums";
|
|
33
|
-
const
|
|
34
|
+
const _props = defineProps({
|
|
34
35
|
tag: { type: String, required: false, default: "div" },
|
|
35
36
|
variant: { type: null, required: false, default: TAB_VARIANT.DEFAULT },
|
|
36
37
|
fixed: { type: Boolean, required: false, default: false },
|
|
@@ -54,6 +55,7 @@ const props = defineProps({
|
|
|
54
55
|
max: { type: Number, required: false },
|
|
55
56
|
selectedClass: { type: String, required: false, default: "origam-tab--active" }
|
|
56
57
|
});
|
|
58
|
+
const props = useDefaults(_props);
|
|
57
59
|
defineEmits(["update:modelValue"]);
|
|
58
60
|
const { filterProps } = useProps(props);
|
|
59
61
|
const { isSelected, select, next, prev, selected, items } = useGroup(props, ORIGAM_TABS_KEY);
|
|
@@ -165,6 +165,8 @@ defineExpose(forwardRefs({
|
|
|
165
165
|
.origam-tooltip__content {
|
|
166
166
|
background-color: var(--origam-tooltip---background-color, var(--origam-color__neutral---800));
|
|
167
167
|
color: var(--origam-tooltip---color, var(--origam-color__text---inverse));
|
|
168
|
+
backdrop-filter: var(--origam-tooltip---backdrop-filter, none);
|
|
169
|
+
-webkit-backdrop-filter: var(--origam-tooltip---backdrop-filter, none);
|
|
168
170
|
font-size: var(--origam-tooltip---font-size, 0.75rem);
|
|
169
171
|
font-weight: var(--origam-tooltip---font-weight, 500);
|
|
170
172
|
line-height: var(--origam-tooltip---line-height, 1.5);
|
|
@@ -6,24 +6,28 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.createDefaults = createDefaults;
|
|
7
7
|
exports.provideDefaults = provideDefaults;
|
|
8
8
|
exports.useDefaults = useDefaults;
|
|
9
|
+
exports.usePassedProps = usePassedProps;
|
|
9
10
|
var _vue = require("vue");
|
|
10
11
|
var _consts = require("../../consts/index.cjs");
|
|
11
12
|
var _utils = require("../../utils/index.cjs");
|
|
12
13
|
function camelize(str) {
|
|
13
14
|
return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
14
15
|
}
|
|
15
|
-
function
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const propNames = Object.keys(props);
|
|
19
|
-
if (!propNames.length) return props;
|
|
20
|
-
const wasPropPassed = key => {
|
|
16
|
+
function usePassedProps(_props, instanceLabel = "usePassedProps") {
|
|
17
|
+
const vm = (0, _utils.getCurrentInstance)(instanceLabel);
|
|
18
|
+
return key => {
|
|
21
19
|
const vnodeProps = vm.vnode.props || {};
|
|
22
20
|
for (const k in vnodeProps) {
|
|
23
21
|
if (k === key || camelize(k) === key) return true;
|
|
24
22
|
}
|
|
25
23
|
return false;
|
|
26
24
|
};
|
|
25
|
+
}
|
|
26
|
+
function useDefaults(props, name = (0, _utils.getCurrentInstanceName)()) {
|
|
27
|
+
const defaults = (0, _vue.inject)(_consts.ORIGAM_DEFAULTS_KEY, (0, _vue.ref)({}));
|
|
28
|
+
const propNames = Object.keys(props);
|
|
29
|
+
if (!propNames.length) return props;
|
|
30
|
+
const wasPropPassed = usePassedProps(props, "useDefaults");
|
|
27
31
|
const result = {};
|
|
28
32
|
for (const key of propNames) {
|
|
29
33
|
const c = (0, _vue.computed)(() => {
|
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
import { type Ref } from 'vue';
|
|
2
2
|
import type { IDefault } from '../../interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* Was-prop-passed factory.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* Component-side primitive: for the CURRENT component instance, returns a
|
|
8
|
+
* predicate telling whether a given prop key was explicitly written by the
|
|
9
|
+
* parent template (`vnode.props`) — as opposed to resolved from a default
|
|
10
|
+
* (`withDefaults()`, or Vue's own boolean-prop coercion).
|
|
11
|
+
*
|
|
12
|
+
* This matters beyond `useDefaults()` itself: any component that FORWARDS
|
|
13
|
+
* its own props down to descendants as `<OrigamDefaultsProvider>` entries
|
|
14
|
+
* (e.g. `OrigamAvatarGroup` → `origam-avatar`, `OrigamBtnGroup` → `origam-btn`)
|
|
15
|
+
* must use this — not a plain `!== undefined` check — to decide whether to
|
|
16
|
+
* forward a value. Reason: Vue resolves an UNSET prop whose declared type
|
|
17
|
+
* *includes* `boolean` (e.g. `border?: boolean | string`, `rounded?: boolean
|
|
18
|
+
* | TRounded`) to the concrete value `false`, never to `undefined`. A naive
|
|
19
|
+
* `omitUndefined()` over the forwarded map therefore still ships an explicit
|
|
20
|
+
* `false` for `border`/`rounded` even when the consumer never set them,
|
|
21
|
+
* which then wins the `mergeDeep` against an ancestor/theme default (e.g.
|
|
22
|
+
* `origam-avatar: { border: true }`) — see #263.
|
|
23
|
+
*
|
|
24
|
+
* MUST be re-read on every resolution (not captured once), for the same
|
|
25
|
+
* reason `useDefaults()` re-reads it: a parent binding through a dynamic
|
|
26
|
+
* `v-bind` whose object starts empty (`childRef?.filterProps(...)` before
|
|
27
|
+
* mount) only fills `vnode.props` on a later render.
|
|
28
|
+
*/
|
|
29
|
+
/*********************************************************
|
|
30
|
+
* usePassedProps
|
|
31
|
+
********************************************************/
|
|
32
|
+
export declare function usePassedProps<T extends Record<string, any>>(_props: T, instanceLabel?: string): (key: Extract<keyof T, string> | string) => boolean;
|
|
3
33
|
/**
|
|
4
34
|
* Component-side hook: resolve `props` against the closest DefaultsProvider.
|
|
5
35
|
*
|
|
@@ -4,18 +4,21 @@ import { getCurrentInstance, getCurrentInstanceName, mergeDeep } from "../../uti
|
|
|
4
4
|
function camelize(str) {
|
|
5
5
|
return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
6
6
|
}
|
|
7
|
-
export function
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const propNames = Object.keys(props);
|
|
11
|
-
if (!propNames.length) return props;
|
|
12
|
-
const wasPropPassed = (key) => {
|
|
7
|
+
export function usePassedProps(_props, instanceLabel = "usePassedProps") {
|
|
8
|
+
const vm = getCurrentInstance(instanceLabel);
|
|
9
|
+
return (key) => {
|
|
13
10
|
const vnodeProps = vm.vnode.props || {};
|
|
14
11
|
for (const k in vnodeProps) {
|
|
15
12
|
if (k === key || camelize(k) === key) return true;
|
|
16
13
|
}
|
|
17
14
|
return false;
|
|
18
15
|
};
|
|
16
|
+
}
|
|
17
|
+
export function useDefaults(props, name = getCurrentInstanceName()) {
|
|
18
|
+
const defaults = inject(ORIGAM_DEFAULTS_KEY, ref({}));
|
|
19
|
+
const propNames = Object.keys(props);
|
|
20
|
+
if (!propNames.length) return props;
|
|
21
|
+
const wasPropPassed = usePassedProps(props, "useDefaults");
|
|
19
22
|
const result = {};
|
|
20
23
|
for (const key of propNames) {
|
|
21
24
|
const c = computed(() => {
|
|
@@ -10,30 +10,47 @@ exports.readPersistedMode = readPersistedMode;
|
|
|
10
10
|
exports.readPersistedTheme = readPersistedTheme;
|
|
11
11
|
exports.useTheme = useTheme;
|
|
12
12
|
var _vue = require("vue");
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
var _theme = require("../../consts/Theme/theme.const.cjs");
|
|
14
|
+
const ORIGAM_THEME_SINGLETON_KEY = "__origamThemeSingleton__";
|
|
15
|
+
const _serverSingleton = {
|
|
16
|
+
theme: null,
|
|
17
|
+
mode: null,
|
|
18
|
+
systemPrefersDark: null,
|
|
19
|
+
mediaInitDone: false
|
|
20
|
+
};
|
|
21
|
+
function themeSingleton() {
|
|
22
|
+
if (typeof window === "undefined") return _serverSingleton;
|
|
23
|
+
const globalScope = globalThis;
|
|
24
|
+
if (!globalScope[ORIGAM_THEME_SINGLETON_KEY]) {
|
|
25
|
+
globalScope[ORIGAM_THEME_SINGLETON_KEY] = {
|
|
26
|
+
theme: null,
|
|
27
|
+
mode: null,
|
|
28
|
+
systemPrefersDark: null,
|
|
29
|
+
mediaInitDone: false
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return globalScope[ORIGAM_THEME_SINGLETON_KEY];
|
|
33
|
+
}
|
|
18
34
|
function ensureSystemPreference() {
|
|
19
|
-
|
|
20
|
-
|
|
35
|
+
const state = themeSingleton();
|
|
36
|
+
if (state.systemPrefersDark === null) {
|
|
37
|
+
state.systemPrefersDark = (0, _vue.ref)(false);
|
|
21
38
|
}
|
|
22
|
-
if (
|
|
23
|
-
return
|
|
39
|
+
if (state.mediaInitDone || typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
40
|
+
return state.systemPrefersDark;
|
|
24
41
|
}
|
|
25
|
-
|
|
42
|
+
state.mediaInitDone = true;
|
|
26
43
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
27
|
-
|
|
44
|
+
state.systemPrefersDark.value = mq.matches;
|
|
28
45
|
mq.addEventListener?.("change", e => {
|
|
29
|
-
if (
|
|
46
|
+
if (state.systemPrefersDark) state.systemPrefersDark.value = e.matches;
|
|
30
47
|
});
|
|
31
|
-
return
|
|
48
|
+
return state.systemPrefersDark;
|
|
32
49
|
}
|
|
33
50
|
function readPersisted() {
|
|
34
51
|
if (typeof window === "undefined") return "auto";
|
|
35
52
|
try {
|
|
36
|
-
const v = window.localStorage?.getItem(
|
|
53
|
+
const v = window.localStorage?.getItem(_theme.ORIGAM_THEME_STORAGE_KEY);
|
|
37
54
|
if (v === "auto" || v === "light" || v === "dark") return v;
|
|
38
55
|
if (v && typeof v === "string") return v;
|
|
39
56
|
} catch {}
|
|
@@ -42,21 +59,21 @@ function readPersisted() {
|
|
|
42
59
|
function writePersisted(theme) {
|
|
43
60
|
if (typeof window === "undefined") return;
|
|
44
61
|
try {
|
|
45
|
-
window.localStorage?.setItem(
|
|
62
|
+
window.localStorage?.setItem(_theme.ORIGAM_THEME_STORAGE_KEY, theme);
|
|
46
63
|
} catch {}
|
|
47
64
|
}
|
|
48
65
|
function applyToDocument(theme) {
|
|
49
66
|
if (typeof document === "undefined") return;
|
|
50
67
|
if (theme === "auto") {
|
|
51
|
-
document.documentElement.removeAttribute(
|
|
68
|
+
document.documentElement.removeAttribute(_theme.ORIGAM_THEME_ATTR);
|
|
52
69
|
} else {
|
|
53
|
-
document.documentElement.setAttribute(
|
|
70
|
+
document.documentElement.setAttribute(_theme.ORIGAM_THEME_ATTR, theme);
|
|
54
71
|
}
|
|
55
72
|
}
|
|
56
73
|
function readPersistedModeValue() {
|
|
57
74
|
if (typeof window === "undefined") return "auto";
|
|
58
75
|
try {
|
|
59
|
-
const v = window.localStorage?.getItem(
|
|
76
|
+
const v = window.localStorage?.getItem(_theme.ORIGAM_MODE_STORAGE_KEY);
|
|
60
77
|
if (v === "auto" || v === "light" || v === "dark") return v;
|
|
61
78
|
} catch {}
|
|
62
79
|
return "auto";
|
|
@@ -64,22 +81,23 @@ function readPersistedModeValue() {
|
|
|
64
81
|
function writePersistedMode(mode) {
|
|
65
82
|
if (typeof window === "undefined") return;
|
|
66
83
|
try {
|
|
67
|
-
window.localStorage?.setItem(
|
|
84
|
+
window.localStorage?.setItem(_theme.ORIGAM_MODE_STORAGE_KEY, mode);
|
|
68
85
|
} catch {}
|
|
69
86
|
}
|
|
70
87
|
function applyModeToDocument(resolvedMode) {
|
|
71
88
|
if (typeof document === "undefined") return;
|
|
72
|
-
document.documentElement.setAttribute(
|
|
89
|
+
document.documentElement.setAttribute(_theme.ORIGAM_MODE_ATTR, resolvedMode);
|
|
73
90
|
}
|
|
74
91
|
function useTheme() {
|
|
75
|
-
|
|
76
|
-
|
|
92
|
+
const state = themeSingleton();
|
|
93
|
+
if (state.theme === null) {
|
|
94
|
+
state.theme = (0, _vue.ref)(readPersisted());
|
|
77
95
|
}
|
|
78
|
-
if (
|
|
79
|
-
|
|
96
|
+
if (state.mode === null) {
|
|
97
|
+
state.mode = (0, _vue.ref)(readPersistedModeValue());
|
|
80
98
|
}
|
|
81
|
-
const theme =
|
|
82
|
-
const mode =
|
|
99
|
+
const theme = state.theme;
|
|
100
|
+
const mode = state.mode;
|
|
83
101
|
const systemPrefersDark = ensureSystemPreference();
|
|
84
102
|
const resolved = (0, _vue.computed)(() => {
|
|
85
103
|
if (theme.value === "auto") return systemPrefersDark.value ? "dark" : "light";
|
|
@@ -146,8 +164,9 @@ function readPersistedMode() {
|
|
|
146
164
|
return readPersistedModeValue();
|
|
147
165
|
}
|
|
148
166
|
function _resetThemeForTesting() {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
167
|
+
const state = themeSingleton();
|
|
168
|
+
state.theme = null;
|
|
169
|
+
state.mode = null;
|
|
170
|
+
state.systemPrefersDark = null;
|
|
171
|
+
state.mediaInitDone = false;
|
|
153
172
|
}
|
|
@@ -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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
14
|
-
|
|
29
|
+
const state = themeSingleton();
|
|
30
|
+
if (state.systemPrefersDark === null) {
|
|
31
|
+
state.systemPrefersDark = ref(false);
|
|
15
32
|
}
|
|
16
|
-
if (
|
|
17
|
-
return
|
|
33
|
+
if (state.mediaInitDone || typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
34
|
+
return state.systemPrefersDark;
|
|
18
35
|
}
|
|
19
|
-
|
|
36
|
+
state.mediaInitDone = true;
|
|
20
37
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
21
|
-
|
|
38
|
+
state.systemPrefersDark.value = mq.matches;
|
|
22
39
|
mq.addEventListener?.("change", (e) => {
|
|
23
|
-
if (
|
|
40
|
+
if (state.systemPrefersDark) state.systemPrefersDark.value = e.matches;
|
|
24
41
|
});
|
|
25
|
-
return
|
|
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
|
-
|
|
74
|
-
|
|
90
|
+
const state = themeSingleton();
|
|
91
|
+
if (state.theme === null) {
|
|
92
|
+
state.theme = ref(readPersisted());
|
|
75
93
|
}
|
|
76
|
-
if (
|
|
77
|
-
|
|
94
|
+
if (state.mode === null) {
|
|
95
|
+
state.mode = ref(readPersistedModeValue());
|
|
78
96
|
}
|
|
79
|
-
const theme =
|
|
80
|
-
const 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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
/**
|
|
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
|
|
6
|
-
* `true` (left) and `false` (right) sides of the
|
|
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
|
-
/**
|
|
25
|
-
|
|
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"
|
|
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"
|
|
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" },
|