@ui0/theme 0.0.0-stage → 0.1.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/README.md +113 -2
- package/dist/backdrop.module.css +1 -0
- package/dist/backdrop.scss +7 -0
- package/dist/color.inject.module.css +7 -0
- package/dist/color.module.css +3 -0
- package/dist/color.scss +84 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +53 -0
- package/dist/components/style.css +1 -0
- package/dist/components/theme-provider.keys.d.ts +4 -0
- package/dist/components/theme-provider.keys.d.ts.map +1 -0
- package/dist/components/theme-provider.module.css +1 -0
- package/dist/components/theme-provider.types.d.ts +18 -0
- package/dist/components/theme-provider.types.d.ts.map +1 -0
- package/dist/components/theme-provider.vue.d.ts +19 -0
- package/dist/config.default.d.mts +4 -0
- package/dist/config.default.d.mts.map +1 -0
- package/dist/config.default.mjs +73 -0
- package/dist/config.default.mjs.map +1 -0
- package/dist/disabled.inject.module.css +5 -0
- package/dist/disabled.module.css +1 -0
- package/dist/disabled.scss +3 -0
- package/dist/display.module.css +2 -0
- package/dist/display.scss +63 -0
- package/dist/duration.scss +17 -0
- package/dist/elevation.module.css +33 -0
- package/dist/elevation.scss +46 -0
- package/dist/generate-BPYE5ALG.mjs +1037 -0
- package/dist/generate-BPYE5ALG.mjs.map +1 -0
- package/dist/generator/cli.d.mts +1 -0
- package/dist/generator/cli.mjs +103 -0
- package/dist/generator/cli.mjs.map +1 -0
- package/dist/generator/vite.d.mts +18 -0
- package/dist/generator/vite.d.mts.map +1 -0
- package/dist/generator/vite.mjs +117 -0
- package/dist/generator/vite.mjs.map +1 -0
- package/dist/index.d.mts +339 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +909 -0
- package/dist/index.mjs.map +1 -0
- package/dist/is.scss +185 -0
- package/dist/load-config-64q6nzFy.mjs +48 -0
- package/dist/load-config-64q6nzFy.mjs.map +1 -0
- package/dist/ripple.scss +57 -0
- package/dist/round.inject.module.css +92 -0
- package/dist/round.module.css +14 -0
- package/dist/round.scss +90 -0
- package/dist/size.inject.module.css +50 -0
- package/dist/size.module.css +13 -0
- package/dist/size.scss +28 -0
- package/dist/theme.scss +16 -0
- package/dist/typography.inject.module.css +81 -0
- package/dist/typography.module.css +32 -0
- package/dist/typography.scss +21 -0
- package/dist/util.scss +78 -0
- package/dist/vars.scss +0 -0
- package/package.json +96 -4
- package/src/contracts/backdrop/backdrop.contract.ts +44 -0
- package/src/contracts/backdrop/backdrop.generator.ts +82 -0
- package/src/contracts/backdrop/backdrop.keys.ts +7 -0
- package/src/contracts/backdrop/backdrop.module.css +3 -0
- package/src/contracts/backdrop/backdrop.scss +7 -0
- package/src/contracts/backdrop/backdrop.types.ts +45 -0
- package/src/contracts/backdrop/index.ts +21 -0
- package/src/contracts/color/color.contract.spec.ts +75 -0
- package/src/contracts/color/color.contract.ts +97 -0
- package/src/contracts/color/color.generator.spec.ts +73 -0
- package/src/contracts/color/color.generator.ts +122 -0
- package/src/contracts/color/color.gradient.spec.ts +32 -0
- package/src/contracts/color/color.gradient.ts +52 -0
- package/src/contracts/color/color.inject.module.css +5 -0
- package/src/contracts/color/color.keys.ts +7 -0
- package/src/contracts/color/color.module.css +5 -0
- package/src/contracts/color/color.scss +84 -0
- package/src/contracts/color/color.serialize.spec.ts +57 -0
- package/src/contracts/color/color.serialize.ts +35 -0
- package/src/contracts/color/color.token.spec.ts +57 -0
- package/src/contracts/color/color.token.ts +89 -0
- package/src/contracts/color/color.types.ts +82 -0
- package/src/contracts/color/index.md +87 -0
- package/src/contracts/color/index.ts +25 -0
- package/src/contracts/contract.ts +115 -0
- package/src/contracts/disabled/disabled.contract.ts +32 -0
- package/src/contracts/disabled/disabled.generator.ts +32 -0
- package/src/contracts/disabled/disabled.inject.module.css +5 -0
- package/src/contracts/disabled/disabled.keys.ts +6 -0
- package/src/contracts/disabled/disabled.module.css +3 -0
- package/src/contracts/disabled/disabled.scss +3 -0
- package/src/contracts/disabled/disabled.types.ts +19 -0
- package/src/contracts/disabled/index.ts +21 -0
- package/src/contracts/display/display.contract.ts +41 -0
- package/src/contracts/display/display.generator.ts +57 -0
- package/src/contracts/display/display.instance.ts +173 -0
- package/src/contracts/display/display.keys.ts +9 -0
- package/src/contracts/display/display.module.css +4 -0
- package/src/contracts/display/display.scss +63 -0
- package/src/contracts/display/display.types.ts +75 -0
- package/src/contracts/display/index.ts +27 -0
- package/src/contracts/elevation/elevation.contract.ts +37 -0
- package/src/contracts/elevation/elevation.generator.ts +71 -0
- package/src/contracts/elevation/elevation.keys.ts +6 -0
- package/src/contracts/elevation/elevation.module.css +35 -0
- package/src/contracts/elevation/elevation.scss +46 -0
- package/src/contracts/elevation/elevation.types.ts +21 -0
- package/src/contracts/elevation/index.ts +20 -0
- package/src/contracts/generator.ts +38 -0
- package/src/contracts/index.md +48 -0
- package/src/contracts/index.ts +37 -0
- package/src/contracts/round/index.ts +21 -0
- package/src/contracts/round/round.contract.ts +75 -0
- package/src/contracts/round/round.generator.ts +33 -0
- package/src/contracts/round/round.inject.module.scss +36 -0
- package/src/contracts/round/round.keys.ts +7 -0
- package/src/contracts/round/round.module.css +16 -0
- package/src/contracts/round/round.scss +90 -0
- package/src/contracts/round/round.types.ts +44 -0
- package/src/contracts/size/index.ts +22 -0
- package/src/contracts/size/size.contract.ts +98 -0
- package/src/contracts/size/size.generator.spec.ts +101 -0
- package/src/contracts/size/size.generator.ts +51 -0
- package/src/contracts/size/size.inject.module.scss +12 -0
- package/src/contracts/size/size.keys.ts +8 -0
- package/src/contracts/size/size.module.css +15 -0
- package/src/contracts/size/size.scss +28 -0
- package/src/contracts/size/size.types.ts +63 -0
- package/src/contracts/size/units.scss +17 -0
- package/src/contracts/style/index.ts +11 -0
- package/src/contracts/style/style.generator.ts +36 -0
- package/src/contracts/style/style.key.ts +4 -0
- package/src/contracts/style/style.types.ts +16 -0
- package/src/contracts/typography/index.ts +26 -0
- package/src/contracts/typography/typography.contract.ts +52 -0
- package/src/contracts/typography/typography.generator.spec.ts +48 -0
- package/src/contracts/typography/typography.generator.ts +44 -0
- package/src/contracts/typography/typography.inject.module.css +54 -0
- package/src/contracts/typography/typography.keys.ts +12 -0
- package/src/contracts/typography/typography.module.css +36 -0
- package/src/contracts/typography/typography.scss +21 -0
- package/src/contracts/typography/typography.types.ts +90 -0
- package/src/generator/theme.default.css +657 -0
- package/src/styles/duration.scss +17 -0
- package/src/styles/index.md +18 -0
- package/src/styles/is.scss +185 -0
- package/src/styles/ripple.scss +57 -0
- package/src/styles/theme.scss +16 -0
- package/src/styles/util.scss +78 -0
- package/src/styles/vars.scss +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ComponentElevation } from '@ui0/types'
|
|
2
|
+
|
|
3
|
+
export interface ElevationProps {
|
|
4
|
+
elevation?: ComponentElevation
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ElevationThemeAppearanceConfig {
|
|
8
|
+
steps?: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// registration: the contract announces itself to the package registries
|
|
12
|
+
// (interface merging - no central import of the contracts anywhere)
|
|
13
|
+
declare module '@ui0/types/theme' {
|
|
14
|
+
interface Ui0ThemePresetAppearanceConfig {
|
|
15
|
+
elevation?: ElevationThemeAppearanceConfig
|
|
16
|
+
}
|
|
17
|
+
interface Ui0ThemeContractSettings {
|
|
18
|
+
elevation?: boolean
|
|
19
|
+
}
|
|
20
|
+
interface Ui0ThemeContracts extends ElevationProps {}
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ThemeContract } from '@ui0/types'
|
|
2
|
+
|
|
3
|
+
import { ThemeContractFlags } from '../../constants'
|
|
4
|
+
import { elevationDeal } from './elevation.contract'
|
|
5
|
+
import { ElevationContractKey, ElevationRefKey } from './elevation.keys'
|
|
6
|
+
import type { ElevationProps } from './elevation.types'
|
|
7
|
+
|
|
8
|
+
export { default as $style } from './elevation.module.css'
|
|
9
|
+
export type * from './elevation.types'
|
|
10
|
+
export * from './elevation.keys'
|
|
11
|
+
export const ElevationPropsKeys: ReadonlyArray<keyof ElevationProps> = ['elevation']
|
|
12
|
+
|
|
13
|
+
export const elevation: ThemeContract = {
|
|
14
|
+
key: ElevationContractKey,
|
|
15
|
+
name: 'elevation',
|
|
16
|
+
ref: ElevationRefKey,
|
|
17
|
+
deal: elevationDeal,
|
|
18
|
+
flag: ThemeContractFlags.dealer + ThemeContractFlags.generator,
|
|
19
|
+
props: ElevationPropsKeys
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Contract generator infra - the context a contract factory receives from
|
|
2
|
+
// the orchestrator (src/generator/contracts.ts) and the factory type every
|
|
3
|
+
// <name>.generator.ts implements. A contract generator turns its slice of
|
|
4
|
+
// the preset's settings (Ui0ThemeConfig.<name>) into CSS: the class rules
|
|
5
|
+
// (css()) plus the vars it wants hoisted into the theme blocks (vars()).
|
|
6
|
+
// The values are authored in the theme config; the contract only wires its
|
|
7
|
+
// prop values onto them.
|
|
8
|
+
import type {
|
|
9
|
+
ThemeContractGenerator,
|
|
10
|
+
ThemePresetName,
|
|
11
|
+
Ui0ThemePresetAppearanceConfig,
|
|
12
|
+
Ui0ThemeContractSettings
|
|
13
|
+
} from '@ui0/types'
|
|
14
|
+
|
|
15
|
+
export interface ContractContext {
|
|
16
|
+
/** the preset this generator instance is created for */
|
|
17
|
+
presetName: ThemePresetName
|
|
18
|
+
/**
|
|
19
|
+
* the resolved appearance config (extends flattened, base merged under
|
|
20
|
+
* the scheme) the vars are generated from
|
|
21
|
+
*/
|
|
22
|
+
config: Ui0ThemePresetAppearanceConfig
|
|
23
|
+
/**
|
|
24
|
+
* the consumer-side contract settings (ThemePluginConfig.contracts) - a
|
|
25
|
+
* contract reads its own slice to toggle behavior preset-independently
|
|
26
|
+
* (e.g. which backdrop functions ship at all)
|
|
27
|
+
*/
|
|
28
|
+
settings: Ui0ThemeContractSettings
|
|
29
|
+
/** class-name hasher - the same algorithm the distiller hashes module.css with */
|
|
30
|
+
hash: (name: string) => string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type ContractFactory = (ctx: ContractContext) => ThemeContractGenerator
|
|
34
|
+
|
|
35
|
+
/** identity helper so a <name>.generator.ts gets its factory context-typed */
|
|
36
|
+
export function defineContract(factory: ContractFactory): ContractFactory {
|
|
37
|
+
return factory
|
|
38
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<size>/ - one folder per component prop contract
|
|
2
|
+
|
|
3
|
+
<size>.module.css the class registry - the single source of logical names
|
|
4
|
+
<size>.inject.module.scss (or .css) the contract's own static css: rules with
|
|
5
|
+
plain logical selectors whose names are imported from the registry
|
|
6
|
+
(`@value name from './<size>.module.css';`); the build compiles it (sass for
|
|
7
|
+
scss), validates the imports against the registry and the selectors against
|
|
8
|
+
the imports, hashes the selectors (same name-only hash) and inlines the result
|
|
9
|
+
into the generated theme.css; the generator imports it as a string and
|
|
10
|
+
returns it from css(), class() re-exports the registry map
|
|
11
|
+
<size>.scss the matching mixin(s) (@use '@ui0/theme/<size>')
|
|
12
|
+
<size>.types.ts the prop typing (Sizeable and friends)
|
|
13
|
+
<size>.generator.ts the generator endpoint (default-exported factory): theme
|
|
14
|
+
vars + setter classes; may optionally expose localScss() - config-generated
|
|
15
|
+
scss data (varName -> value, like the display breakpoints) the consumer's
|
|
16
|
+
loader writes next to theme.css as <size>.scss
|
|
17
|
+
|
|
18
|
+
Each contract also builds into the package dist (@ui0/vite/css-modules -
|
|
19
|
+
ui0CssModulesHash, wired via scripts/build-contracts.ts and the theme
|
|
20
|
+
tsdown/vitest configs):
|
|
21
|
+
<size>.scss -> dist/<size>.scss (source copy, relative @use rewritten to
|
|
22
|
+
package exports) and <size>.module.css -> dist/<size>.module.css as
|
|
23
|
+
`@value className: classHash;` lines - the shipped names for consumers.
|
|
24
|
+
An inject module additionally distills to dist/<size>.inject.module.css
|
|
25
|
+
(`@value name: hash;` map lines + the hashed css).
|
|
26
|
+
The hash (name-only sha256 inside ui0-css-modules-hash.ts) is the same one
|
|
27
|
+
the plugin hands to TS imports. The same plugin serves component packages:
|
|
28
|
+
ui0CssModulesHash({ entries: ['src/components'] }) distills every
|
|
29
|
+
`<component>.module.css` the same way.
|
|
30
|
+
|
|
31
|
+
color/ the paint contract (color/fill/gradient) - see color/index.md for the
|
|
32
|
+
v2 prop dsl, the ColorToken type and the delivery model. v1 is archived at
|
|
33
|
+
color-legacy/ (unregistered, reference only)
|
|
34
|
+
size/ size.scss size.module.css size.types.ts
|
|
35
|
+
round/ round.scss round.module.css round.types.ts
|
|
36
|
+
backdrop/ backdrop.scss backdrop.module.css backdrop.types.ts
|
|
37
|
+
elevation/ elevation.scss elevation.module.css elevation.types.ts
|
|
38
|
+
disabled/ disabled.scss disabled.module.css disabled.types.ts
|
|
39
|
+
|
|
40
|
+
The generator registry lives at src/generator.ts (contractGenerators) -
|
|
41
|
+
external contracts will merge their default-exported factories there (or pass
|
|
42
|
+
their own map to runContractGenerators' `factories` param).
|
|
43
|
+
|
|
44
|
+
useThemeContract.ts / useThemeContract.spec.ts
|
|
45
|
+
The useThemeContract(props, $styles) composable: a component-context
|
|
46
|
+
bridge over the contracts - provides/injects the prop refs (color, fill,
|
|
47
|
+
round, size, density, elevation, backdrop, disabled) for descendants and feeds
|
|
48
|
+
them to ContractProvider from contract.ts.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ThemeContract, ThemeContractName } from '@ui0/types'
|
|
2
|
+
|
|
3
|
+
import { backdrop, BackdropPropsKeys } from './backdrop'
|
|
4
|
+
import { color, ColorPropsKeys } from './color'
|
|
5
|
+
import { disabled, DisabledPropsKeys } from './disabled'
|
|
6
|
+
import { display } from './display'
|
|
7
|
+
import { elevation, ElevationPropsKeys } from './elevation'
|
|
8
|
+
import { round, RoundPropsKeys } from './round'
|
|
9
|
+
import { size, SizePropsKeys } from './size'
|
|
10
|
+
import { style } from './style'
|
|
11
|
+
import { typography } from './typography'
|
|
12
|
+
export type * from './backdrop'
|
|
13
|
+
export type * from './color'
|
|
14
|
+
export type * from './disabled'
|
|
15
|
+
export type * from './elevation'
|
|
16
|
+
export type * from './round'
|
|
17
|
+
export type * from './size'
|
|
18
|
+
|
|
19
|
+
export const contracts: Record<ThemeContractName, ThemeContract> = {
|
|
20
|
+
color,
|
|
21
|
+
backdrop,
|
|
22
|
+
round,
|
|
23
|
+
elevation,
|
|
24
|
+
style,
|
|
25
|
+
disabled,
|
|
26
|
+
display,
|
|
27
|
+
typography,
|
|
28
|
+
size
|
|
29
|
+
}
|
|
30
|
+
export const props = [
|
|
31
|
+
ColorPropsKeys,
|
|
32
|
+
RoundPropsKeys,
|
|
33
|
+
SizePropsKeys,
|
|
34
|
+
ElevationPropsKeys,
|
|
35
|
+
BackdropPropsKeys,
|
|
36
|
+
DisabledPropsKeys
|
|
37
|
+
].flat()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ThemeContract } from '@ui0/types'
|
|
2
|
+
|
|
3
|
+
import { ThemeContractFlags } from '../../constants'
|
|
4
|
+
import { roundDeal } from './round.contract'
|
|
5
|
+
import { RoundContractKey, RoundRefKey } from './round.keys'
|
|
6
|
+
import type { RoundProps } from './round.types'
|
|
7
|
+
|
|
8
|
+
export { default as $style } from './round.module.css'
|
|
9
|
+
export type * from './round.types'
|
|
10
|
+
export * from './round.keys'
|
|
11
|
+
|
|
12
|
+
export const RoundPropsKeys: ReadonlyArray<keyof RoundProps> = ['round', 'round-target']
|
|
13
|
+
|
|
14
|
+
export const round: ThemeContract = {
|
|
15
|
+
key: RoundContractKey,
|
|
16
|
+
name: 'round',
|
|
17
|
+
ref: RoundRefKey,
|
|
18
|
+
deal: roundDeal,
|
|
19
|
+
flag: ThemeContractFlags.dealer + ThemeContractFlags.generator,
|
|
20
|
+
props: RoundPropsKeys
|
|
21
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// The round contract's processing endpoint. The runtime wiring is minimal
|
|
2
|
+
// for now: radius values are computed in the component namespace
|
|
3
|
+
// (round.scss) and no round settings land on the theme block yet - the deal
|
|
4
|
+
// returns no classes until a rounding setting arrives in the config.
|
|
5
|
+
import type { CSSModuleClassList, Indexed } from '@ui0/types'
|
|
6
|
+
import type { ContractProvider, ThemeContractDeal } from '@ui0/types'
|
|
7
|
+
import { mergeCssModulesStyles, propsToCssModuleClassNext } from '@ui0/util'
|
|
8
|
+
|
|
9
|
+
import { EMPTY_OBJ } from '../../constants'
|
|
10
|
+
import type { RoundProps } from './round.types'
|
|
11
|
+
|
|
12
|
+
import $round from './round.module.css'
|
|
13
|
+
export type PropClassImpl<T = Record<string, unknown>> = keyof T | [keyof T, Indexed]
|
|
14
|
+
|
|
15
|
+
export function roundDeal(instance: ContractProvider): ThemeContractDeal {
|
|
16
|
+
return {
|
|
17
|
+
classes() {
|
|
18
|
+
const { props, $styles } = instance
|
|
19
|
+
const $ = mergeCssModulesStyles($round, $styles)
|
|
20
|
+
console.log('props', instance.props)
|
|
21
|
+
|
|
22
|
+
console.log(
|
|
23
|
+
'propsToCssModuleClassNext(props, [getRoundPropClasses($), getRoundTargetPropClasses($)], $)',
|
|
24
|
+
propsToCssModuleClassNext(props, [getRoundPropClasses($), getRoundTargetPropClasses($)], $)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
return propsToCssModuleClassNext(props, [getRoundPropClasses($), getRoundTargetPropClasses($)], $)
|
|
28
|
+
},
|
|
29
|
+
styles: () => instance.inject(EMPTY_OBJ)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getRoundTargetPropClasses(style: CSSModuleClassList = $round): PropClassImpl<RoundProps> {
|
|
34
|
+
return [
|
|
35
|
+
'roundTarget',
|
|
36
|
+
{
|
|
37
|
+
'top-left-none': style.tln,
|
|
38
|
+
'bottom-left-none': style.bln,
|
|
39
|
+
'top-right-none': style.trn,
|
|
40
|
+
'bottom-right-none': style.brn,
|
|
41
|
+
|
|
42
|
+
'top-none': style.tn,
|
|
43
|
+
'bottom-none': style.bn,
|
|
44
|
+
'right-none': style.rn,
|
|
45
|
+
'left-none': style.ln,
|
|
46
|
+
|
|
47
|
+
'bottom-left': style.bl,
|
|
48
|
+
'bottom-right': style.br,
|
|
49
|
+
'top-right': style.tr,
|
|
50
|
+
'top-left': style.tl
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
function getRoundPropClasses(style: CSSModuleClassList = $round): PropClassImpl<RoundProps> {
|
|
55
|
+
return [
|
|
56
|
+
'round',
|
|
57
|
+
{
|
|
58
|
+
true: style.rFull,
|
|
59
|
+
none: style.rNone,
|
|
60
|
+
full: style.rFull,
|
|
61
|
+
|
|
62
|
+
basic: style.rBasic,
|
|
63
|
+
smooth: style.rSmooth,
|
|
64
|
+
hard: style.rHard,
|
|
65
|
+
|
|
66
|
+
round: style.round,
|
|
67
|
+
|
|
68
|
+
left: [style.tl, style.bl],
|
|
69
|
+
|
|
70
|
+
right: [style.tr, style.br],
|
|
71
|
+
bottom: [style.br, style.bl],
|
|
72
|
+
top: [style.tl, style.tr]
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// The round contract's generator endpoint: corner-radius setter classes.
|
|
2
|
+
// The resolved rounding values live in the component namespace (--0c-r-*, see
|
|
3
|
+
// round.scss); a setter class points the per-corner slots at one of
|
|
4
|
+
// them, falling back to the theme-level --0-r-* when the component never ran
|
|
5
|
+
// apply() (its own computed default wins where it did). The setter css is
|
|
6
|
+
// static - it ships in round.inject.module.scss (compiled + hashed at build);
|
|
7
|
+
// class() re-exports the registry map from round.module.css.
|
|
8
|
+
import type { CSSModuleClassList, StyleList } from '@ui0/types'
|
|
9
|
+
import type { ThemeContractGenerator } from '@ui0/types'
|
|
10
|
+
|
|
11
|
+
import type { ContractFactory } from '../generator'
|
|
12
|
+
|
|
13
|
+
import roundCss from './round.inject.module.scss'
|
|
14
|
+
import $round from './round.module.css'
|
|
15
|
+
|
|
16
|
+
const roundGenerator: ContractFactory = (): ThemeContractGenerator => {
|
|
17
|
+
return {
|
|
18
|
+
namespace: 'r',
|
|
19
|
+
vars: () => ({}),
|
|
20
|
+
css: () => roundCss,
|
|
21
|
+
class: (): CSSModuleClassList => ({ ...$round }),
|
|
22
|
+
styles: (): StyleList => ({
|
|
23
|
+
'--0-r-base': '4px',
|
|
24
|
+
'--0-r-tl': '0px',
|
|
25
|
+
'--0-r-tr': '0px',
|
|
26
|
+
'--0-r-bl': '0px',
|
|
27
|
+
'--0-r-basic': 'calc(var(--0-s-m, 42px) * var(--0-s-density, 1))',
|
|
28
|
+
'--0-r-br': '0px'
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default roundGenerator
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@value rFull, rSmooth, rBasic, rHard, rNone, rounded, rl, rr, rt, rb, tl, tr, bl, br from './round.module.css';
|
|
2
|
+
|
|
3
|
+
@mixin corners($name) {
|
|
4
|
+
--0-r-tl: var(--0c-r-#{$name}, var(--0-r-#{$name}));
|
|
5
|
+
--0-r-tr: var(--0c-r-#{$name}, var(--0-r-#{$name}));
|
|
6
|
+
--0-r-bl: var(--0c-r-#{$name}, var(--0-r-#{$name}));
|
|
7
|
+
--0-r-br: var(--0c-r-#{$name}, var(--0-r-#{$name}));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.rFull { @include corners(full); }
|
|
11
|
+
.rSmooth { @include corners(smooth); }
|
|
12
|
+
.rBasic { @include corners(basic); }
|
|
13
|
+
.rHard { @include corners(hard); }
|
|
14
|
+
.rNone { @include corners(none); }
|
|
15
|
+
.rounded { @include corners(basic); }
|
|
16
|
+
|
|
17
|
+
.rl {
|
|
18
|
+
--0-r-tl: var(--0c-r-basic, var(--0-r-basic));
|
|
19
|
+
--0-r-bl: var(--0c-r-basic, var(--0-r-basic));
|
|
20
|
+
}
|
|
21
|
+
.rr {
|
|
22
|
+
--0-r-tr: var(--0c-r-basic, var(--0-r-basic));
|
|
23
|
+
--0-r-br: var(--0c-r-basic, var(--0-r-basic));
|
|
24
|
+
}
|
|
25
|
+
.rt {
|
|
26
|
+
--0-r-tl: var(--0c-r-basic, var(--0-r-basic));
|
|
27
|
+
--0-r-tr: var(--0c-r-basic, var(--0-r-basic));
|
|
28
|
+
}
|
|
29
|
+
.rb {
|
|
30
|
+
--0-r-bl: var(--0c-r-basic, var(--0-r-basic));
|
|
31
|
+
--0-r-br: var(--0c-r-basic, var(--0-r-basic));
|
|
32
|
+
}
|
|
33
|
+
.tl { --0-r-tl: var(--0c-r-basic, var(--0-r-basic)); }
|
|
34
|
+
.tr { --0-r-tr: var(--0c-r-basic, var(--0-r-basic)); }
|
|
35
|
+
.bl { --0-r-bl: var(--0c-r-basic, var(--0-r-basic)); }
|
|
36
|
+
.br { --0-r-br: var(--0c-r-basic, var(--0-r-basic)); }
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ComponentRound, ComponentRoundTarget } from '@ui0/types'
|
|
2
|
+
import type { ThemeContractDeal } from '@ui0/types'
|
|
3
|
+
import type { InjectionKey, Ref } from 'vue'
|
|
4
|
+
|
|
5
|
+
export const RoundRefKey = Symbol('RoundRefKey') as InjectionKey<Ref<ComponentRound>>
|
|
6
|
+
export const RoundTargetRefKey = Symbol('RoundTargetRefKey') as InjectionKey<Ref<ComponentRoundTarget>>
|
|
7
|
+
export const RoundContractKey = Symbol('RoundContractKey') as InjectionKey<ThemeContractDeal>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Corner radius application for a component.
|
|
2
|
+
//
|
|
3
|
+
// Rounding names (--0-r-none/hard/basic/smooth/full) are a THEME concern: the
|
|
4
|
+
// generator emits whatever the config's `roundings` section declares, on the
|
|
5
|
+
// .theme-* rule. This mixin provides a COMPUTED default for each name (a
|
|
6
|
+
// proportion of the control's current height) and resolves it into the
|
|
7
|
+
// --0c-r-* component namespace with the theme value winning via the var()
|
|
8
|
+
// fallback. The resolved defaults MUST live under --0c-r-* (not --0-r-*):
|
|
9
|
+
// a self-referential `--0-r-x: var(--0-r-x, …)` on the element is a CSS cycle
|
|
10
|
+
// (guaranteed-invalid at computed-value time) and kills every consumer - the
|
|
11
|
+
// setter classes read the --0c-r-* names.
|
|
12
|
+
|
|
13
|
+
@mixin init {
|
|
14
|
+
@property --0-r-tl {
|
|
15
|
+
syntax: '<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?';
|
|
16
|
+
inherits: false;
|
|
17
|
+
initial-value: 0;
|
|
18
|
+
}
|
|
19
|
+
@property --0-r-tr {
|
|
20
|
+
syntax: '<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?';
|
|
21
|
+
inherits: false;
|
|
22
|
+
initial-value: 0;
|
|
23
|
+
}
|
|
24
|
+
@property --0-r-bl {
|
|
25
|
+
syntax: '<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?';
|
|
26
|
+
inherits: false;
|
|
27
|
+
initial-value: 0;
|
|
28
|
+
}
|
|
29
|
+
@property --0-r-br {
|
|
30
|
+
syntax: '<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?';
|
|
31
|
+
inherits: false;
|
|
32
|
+
initial-value: 0;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@mixin use() {
|
|
37
|
+
border-start-start-radius: var(--0-r-tl, 0px);
|
|
38
|
+
border-start-end-radius: var(--0-r-tr, 0px);
|
|
39
|
+
border-end-start-radius: var(--0-r-bl, 0px);
|
|
40
|
+
border-end-end-radius: var(--0-r-br, 0px);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// $basic - the size the proportions are taken from; defaults to the control's
|
|
44
|
+
// current (density-aware) height.
|
|
45
|
+
@mixin apply($basic: null) {
|
|
46
|
+
@if $basic == null {
|
|
47
|
+
$basic: calc(var(--0-s-cur, 42px) * var(--0-s-density, 1));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// computed defaults in the component namespace; a theme-declared --0-r-*
|
|
51
|
+
// wins over each via the var() fallback (element-level --0-r-* would be a
|
|
52
|
+
// self-referential cycle, so the names must differ)
|
|
53
|
+
--0c-r-full: var(--0-r-full, calc(#{$basic} / 2));
|
|
54
|
+
--0c-r-smooth: var(--0-r-smooth, calc(#{$basic} / 4));
|
|
55
|
+
--0c-r-basic: var(--0-r-basic, calc(#{$basic} / 8));
|
|
56
|
+
--0c-r-hard: var(--0-r-hard, calc(#{$basic} / 14));
|
|
57
|
+
--0c-r-none: var(--0-r-none, 0px);
|
|
58
|
+
// @include reset();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@mixin full() {
|
|
62
|
+
--0-r-tl: var(--0c-r-full, var(--0-r-full));
|
|
63
|
+
--0-r-tr: var(--0c-r-full, var(--0-r-full));
|
|
64
|
+
--0-r-bl: var(--0c-r-full, var(--0-r-full));
|
|
65
|
+
--0-r-br: var(--0c-r-full, var(--0-r-full));
|
|
66
|
+
}
|
|
67
|
+
@mixin smooth() {
|
|
68
|
+
--0-r-tl: var(--0c-r-smooth, var(--0-r-smooth));
|
|
69
|
+
--0-r-tr: var(--0c-r-smooth, var(--0-r-smooth));
|
|
70
|
+
--0-r-bl: var(--0c-r-smooth, var(--0-r-smooth));
|
|
71
|
+
--0-r-br: var(--0c-r-smooth, var(--0-r-smooth));
|
|
72
|
+
}
|
|
73
|
+
@mixin basic() {
|
|
74
|
+
--0-r-tl: var(--0c-r-basic, var(--0-r-basic));
|
|
75
|
+
--0-r-tr: var(--0c-r-basic, var(--0-r-basic));
|
|
76
|
+
--0-r-bl: var(--0c-r-basic, var(--0-r-basic));
|
|
77
|
+
--0-r-br: var(--0c-r-basic, var(--0-r-basic));
|
|
78
|
+
}
|
|
79
|
+
@mixin hard() {
|
|
80
|
+
--0-r-tl: var(--0c-r-hard, var(--0-r-hard));
|
|
81
|
+
--0-r-tr: var(--0c-r-hard, var(--0-r-hard));
|
|
82
|
+
--0-r-bl: var(--0c-r-hard, var(--0-r-hard));
|
|
83
|
+
--0-r-br: var(--0c-r-hard, var(--0-r-hard));
|
|
84
|
+
}
|
|
85
|
+
@mixin reset() {
|
|
86
|
+
--0-r-tl: 0px;
|
|
87
|
+
--0-r-tr: 0px;
|
|
88
|
+
--0-r-bl: 0px;
|
|
89
|
+
--0-r-br: 0px;
|
|
90
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { InheritValue, LiteralUnion } from '@ui0/types'
|
|
2
|
+
|
|
3
|
+
export interface RoundProps {
|
|
4
|
+
round?: Round
|
|
5
|
+
roundTarget?: RoundTarget
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface RoundThemeAppearanceConfig {
|
|
9
|
+
rounding: 'relative' | 'static'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// registration: the contract announces itself to the package registries
|
|
13
|
+
// (interface merging - no central import of the contracts anywhere)
|
|
14
|
+
declare module '@ui0/types/theme' {
|
|
15
|
+
interface Ui0ThemePresetAppearanceConfig {
|
|
16
|
+
round?: RoundThemeAppearanceConfig
|
|
17
|
+
}
|
|
18
|
+
interface Ui0ThemeContractSettings {
|
|
19
|
+
round?: {
|
|
20
|
+
rounding: 'relative' | 'static'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
interface Ui0ThemeContracts extends RoundProps {}
|
|
24
|
+
}
|
|
25
|
+
export type RoundTarget =
|
|
26
|
+
| InheritValue
|
|
27
|
+
| 'top'
|
|
28
|
+
| 'bottom'
|
|
29
|
+
| 'left'
|
|
30
|
+
| 'right'
|
|
31
|
+
| 'top-none'
|
|
32
|
+
| 'bottom-none'
|
|
33
|
+
| 'left-none'
|
|
34
|
+
| 'right-none'
|
|
35
|
+
| 'top-left'
|
|
36
|
+
| 'top-right'
|
|
37
|
+
| 'bottom-left'
|
|
38
|
+
| 'bottom-right'
|
|
39
|
+
| 'top-left-none'
|
|
40
|
+
| 'top-right-none'
|
|
41
|
+
| 'bottom-left-none'
|
|
42
|
+
| 'bottom-right-none'
|
|
43
|
+
|
|
44
|
+
export type Round = LiteralUnion<InheritValue | 'basic' | 'full' | 'none' | 'hard' | 'smooth'>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ThemeContract } from '@ui0/types'
|
|
2
|
+
|
|
3
|
+
import { ThemeContractFlags } from '../../constants'
|
|
4
|
+
import { sizeDeal } from './size.contract'
|
|
5
|
+
import { SizeContractKey, SizeRefKey } from './size.keys'
|
|
6
|
+
import type { DensityProps, SizeProps } from './size.types'
|
|
7
|
+
|
|
8
|
+
export { default as $style } from './size.module.css'
|
|
9
|
+
export type * from './size.types'
|
|
10
|
+
export * from './size.keys'
|
|
11
|
+
export { default as sizeGenerator } from './size.generator'
|
|
12
|
+
|
|
13
|
+
export const SizePropsKeys: ReadonlyArray<keyof (SizeProps & DensityProps)> = ['size', 'density']
|
|
14
|
+
|
|
15
|
+
export const size: ThemeContract = {
|
|
16
|
+
ref: SizeRefKey,
|
|
17
|
+
name: 'size',
|
|
18
|
+
props: SizePropsKeys,
|
|
19
|
+
deal: sizeDeal,
|
|
20
|
+
flag: ThemeContractFlags.dealer + ThemeContractFlags.generator,
|
|
21
|
+
key: SizeContractKey
|
|
22
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// The size contract's processing endpoint: closes over the provider and
|
|
2
|
+
// returns the deal that maps the `size`/`density` props onto classes,
|
|
3
|
+
// resolving `inherit`/`smaller`/`larger` against the provided context refs.
|
|
4
|
+
import type { ClassList, CSSModuleClassList } from '@ui0/types'
|
|
5
|
+
import type { ContractProvider, ThemeContractDeal } from '@ui0/types'
|
|
6
|
+
import { arrayPickNext, arrayPickPrev, isArray, mergeCssModulesStyles, toCamelCase } from '@ui0/util'
|
|
7
|
+
|
|
8
|
+
import { EMPTY_OBJ } from '../../constants'
|
|
9
|
+
import type { DensityProps, Size, SizeProps } from './size.types'
|
|
10
|
+
import { SizeValuesAbsolute } from './size.types'
|
|
11
|
+
|
|
12
|
+
import $size from './size.module.css'
|
|
13
|
+
|
|
14
|
+
type Sizers = SizeProps & DensityProps
|
|
15
|
+
|
|
16
|
+
function sizeClasses(props: Sizers, styles?: CSSModuleClassList): ClassList {
|
|
17
|
+
const out: ClassList = []
|
|
18
|
+
const { size, density } = props
|
|
19
|
+
const normalizedSizing = (isArray(density) ? density : [toCamelCase(density)]) as string[]
|
|
20
|
+
|
|
21
|
+
const $ = mergeCssModulesStyles($size, styles)
|
|
22
|
+
if (size) {
|
|
23
|
+
out.push($.sized)
|
|
24
|
+
const cls = getSizePropClasses($)[size]
|
|
25
|
+
if (cls) out.push(cls)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (normalizedSizing) {
|
|
29
|
+
normalizedSizing.forEach((d) => {
|
|
30
|
+
if ($ && $[d]) out.push($[d])
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
return out
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getSizePropClasses(styles: CSSModuleClassList): Record<Size | 'inherit', string> {
|
|
37
|
+
return {
|
|
38
|
+
'xxx-large': styles.sizeXxxl,
|
|
39
|
+
'xx-large': styles.sizeXxl,
|
|
40
|
+
'x-large': styles.sizeXl,
|
|
41
|
+
large: styles.sizeL,
|
|
42
|
+
'x-small': styles.sizeXs,
|
|
43
|
+
'xx-small': styles.sizeXxs,
|
|
44
|
+
'xxx-small': styles.sizeXxxs,
|
|
45
|
+
small: styles.sizeS,
|
|
46
|
+
medium: styles.sizeM,
|
|
47
|
+
|
|
48
|
+
xxxl: styles.sizeXxxl,
|
|
49
|
+
xxl: styles.sizeXxl,
|
|
50
|
+
xl: styles.sizeXl,
|
|
51
|
+
l: styles.sizeL,
|
|
52
|
+
xs: styles.sizeXs,
|
|
53
|
+
xxs: styles.sizeXxs,
|
|
54
|
+
xxxs: styles.sizeXxxs,
|
|
55
|
+
s: styles.sizeS,
|
|
56
|
+
m: styles.sizeM,
|
|
57
|
+
|
|
58
|
+
larger: '',
|
|
59
|
+
inherit: '',
|
|
60
|
+
smaller: '',
|
|
61
|
+
custom: styles.sizeCustom
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function sizeDeal(instance: ContractProvider): ThemeContractDeal {
|
|
66
|
+
const props = instance.props
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
classes: () => {
|
|
70
|
+
const { size, density } = props
|
|
71
|
+
if (!size && !density) return instance.inject([])
|
|
72
|
+
|
|
73
|
+
if (instance.context) {
|
|
74
|
+
const out: Record<string, any> = {}
|
|
75
|
+
const ctxSize = instance.context.size
|
|
76
|
+
|
|
77
|
+
if (ctxSize) {
|
|
78
|
+
if (size === 'inherit') out['size'] = ctxSize.value
|
|
79
|
+
if (size === 'smaller' || size === 'larger') {
|
|
80
|
+
out['size'] = (size === 'smaller' ? arrayPickPrev : arrayPickNext)(SizeValuesAbsolute, ctxSize.value)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const ctxDensity = instance.context.density
|
|
84
|
+
if (ctxDensity && density === 'inherit') {
|
|
85
|
+
out['density'] = ctxDensity.value
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!('density' in out) && props.density) out['density'] = props.density
|
|
89
|
+
if (!('size' in out) && props.size) out['size'] = props.size
|
|
90
|
+
|
|
91
|
+
return instance.inject(sizeClasses(out, instance.$styles))
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return instance.inject(sizeClasses(props, instance.$styles))
|
|
95
|
+
},
|
|
96
|
+
styles: () => instance.inject(EMPTY_OBJ)
|
|
97
|
+
}
|
|
98
|
+
}
|