@things-factory/shell 10.1.26 → 10.1.27
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/client/themes/layout-theme.css +7 -7
- package/client/themes/material-theme.css +6 -46
- package/client/themes/spacing.css +11 -9
- package/client/themes/ui-tokens.css +13 -12
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/tests/control-height-tokens.test.ts +31 -60
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/shell",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.27",
|
|
4
4
|
"description": "Core module for framework",
|
|
5
5
|
"bin": {
|
|
6
6
|
"things-factory": "bin/things-factory",
|
|
@@ -126,5 +126,5 @@
|
|
|
126
126
|
"pg": "^8.7.3",
|
|
127
127
|
"sqlite3": "^5.0.8"
|
|
128
128
|
},
|
|
129
|
-
"gitHead": "
|
|
129
|
+
"gitHead": "d04dc762cacf2aac8ba0b0f5d768eca365fc09da"
|
|
130
130
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* together - change one and it fails until the other follows.
|
|
6
6
|
*
|
|
7
7
|
* Two bundles: button heights (ACTION_HEIGHT_TOKENS, ui-tokens.css) and input heights
|
|
8
|
-
* (FORM_ELEMENT_HEIGHT_TOKENS, spacing.css). Material buttons
|
|
9
|
-
*
|
|
8
|
+
* (FORM_ELEMENT_HEIGHT_TOKENS, spacing.css). Material buttons and filter chips are sized once in the
|
|
9
|
+
* theme from those tokens; Material text fields and selects keep their own size.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { existsSync, readFileSync } from 'fs'
|
|
@@ -33,14 +33,19 @@ function themeDeclarations(file: string): Record<string, string> {
|
|
|
33
33
|
return Object.fromEntries([...css.matchAll(/(--[a-z0-9-]+)\s*:\s*([^;]+);/g)].map(m => [m[1], m[2].trim()]))
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
function
|
|
36
|
+
function expectPlatformSlots(constants: Record<string, number>, theme: Record<string, string>) {
|
|
37
|
+
/*
|
|
38
|
+
* Each token opens a slot for operato-suite and falls back to the platform default
|
|
39
|
+
* (ADR-0060 decision 6-1). The suite never redefines the token itself, so nothing depends on which
|
|
40
|
+
* stylesheet loads last.
|
|
41
|
+
*/
|
|
37
42
|
for (const [token, px] of Object.entries(constants)) {
|
|
38
|
-
expect({ token, value: theme[token] }).toEqual({ token, value:
|
|
43
|
+
expect({ token, value: theme[token] }).toEqual({ token, value: `var(--suite-${token.slice(2)}, ${px}px)` })
|
|
39
44
|
}
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
describe('button height tokens', () => {
|
|
43
|
-
it('the shell theme
|
|
48
|
+
it('the shell theme opens every @operato/styles action height as a suite slot over the platform default', () => {
|
|
44
49
|
const constants = stylesConstants('action-heights.js', 'ACTION_HEIGHT_TOKENS')
|
|
45
50
|
|
|
46
51
|
expect(Object.keys(constants).sort()).toEqual([
|
|
@@ -49,7 +54,7 @@ describe('button height tokens', () => {
|
|
|
49
54
|
'--form-action-height',
|
|
50
55
|
'--popup-action-height'
|
|
51
56
|
])
|
|
52
|
-
|
|
57
|
+
expectPlatformSlots(constants, themeDeclarations('ui-tokens.css'))
|
|
53
58
|
})
|
|
54
59
|
|
|
55
60
|
it('Material buttons take the form height, set once in the theme', () => {
|
|
@@ -63,15 +68,19 @@ describe('button height tokens', () => {
|
|
|
63
68
|
}
|
|
64
69
|
})
|
|
65
70
|
|
|
66
|
-
it('assist chips
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
it('assist chips: 36px (44px by finger) on the platform, the page action height in the operato products', () => {
|
|
72
|
+
const css = readFileSync(path.join(THEMES, 'layout-theme.css'), 'utf-8').replace(/\/\*[\s\S]*?\*\//g, '')
|
|
73
|
+
const values = [...css.matchAll(/--md-assist-chip-container-height\s*:\s*([^;]+);/g)].map(m => m[1].trim())
|
|
74
|
+
|
|
75
|
+
expect(values).toEqual([
|
|
76
|
+
'var(--suite-context-action-height, 36px)',
|
|
77
|
+
'var(--suite-context-action-height, var(--ui-tap, 44px))'
|
|
78
|
+
])
|
|
70
79
|
})
|
|
71
80
|
})
|
|
72
81
|
|
|
73
82
|
describe('input height tokens', () => {
|
|
74
|
-
it('the shell theme
|
|
83
|
+
it('the shell theme opens small, medium and large as suite slots over the platform defaults, and nothing else', () => {
|
|
75
84
|
const constants = stylesConstants('form-element-heights.js', 'FORM_ELEMENT_HEIGHT_TOKENS')
|
|
76
85
|
const theme = themeDeclarations('spacing.css')
|
|
77
86
|
|
|
@@ -80,7 +89,7 @@ describe('input height tokens', () => {
|
|
|
80
89
|
'--form-element-height-medium',
|
|
81
90
|
'--form-element-height-small'
|
|
82
91
|
])
|
|
83
|
-
|
|
92
|
+
expectPlatformSlots(constants, theme)
|
|
84
93
|
expect(
|
|
85
94
|
Object.keys(theme)
|
|
86
95
|
.filter(name => name.startsWith('--form-element-height-'))
|
|
@@ -88,55 +97,17 @@ describe('input height tokens', () => {
|
|
|
88
97
|
).toEqual(Object.keys(constants).sort())
|
|
89
98
|
})
|
|
90
99
|
|
|
91
|
-
it('
|
|
92
|
-
/*
|
|
93
|
-
* The tokens are separate so one use can change on its own (user decision 2026-09-17). This test
|
|
94
|
-
* is a layout rule on top of that: a field and a button that stand on one row have one height.
|
|
95
|
-
* If a change here is intended, change this rule - do not put the value back to make it pass.
|
|
96
|
-
*/
|
|
97
|
-
const actions = stylesConstants('action-heights.js', 'ACTION_HEIGHT_TOKENS')
|
|
98
|
-
const inputs = stylesConstants('form-element-heights.js', 'FORM_ELEMENT_HEIGHT_TOKENS')
|
|
99
|
-
const pairs = [
|
|
100
|
-
['--form-element-height-medium', '--form-action-height'],
|
|
101
|
-
['--form-element-height-small', '--cell-action-height']
|
|
102
|
-
] as const
|
|
103
|
-
|
|
104
|
-
for (const [input, button] of pairs) {
|
|
105
|
-
if (inputs[input] !== actions[button]) {
|
|
106
|
-
throw new Error(
|
|
107
|
-
`${input} (${inputs[input]}px) and ${button} (${actions[button]}px) stand on one row but differ in height. ` +
|
|
108
|
-
'If that is intended, change this layout rule; do not put the value back to make it pass.'
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it('outlined Material fields take medium, filled ones take large', () => {
|
|
100
|
+
it('Material text fields, selects and filter chips keep their own size', () => {
|
|
101
|
+
/* Their label floats above the value inside the box and needs the room (user decision). */
|
|
115
102
|
const theme = themeDeclarations('material-theme.css')
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
'--md-outlined-field-top-space',
|
|
122
|
-
'--md-outlined-field-bottom-space'
|
|
123
|
-
]) {
|
|
124
|
-
expect({ name, value: theme[name] }).toEqual({ name, value: space('medium', 20) })
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
for (const name of [
|
|
128
|
-
'--md-filled-text-field-top-space',
|
|
129
|
-
'--md-filled-text-field-bottom-space',
|
|
130
|
-
'--md-filled-field-top-space',
|
|
131
|
-
'--md-filled-field-bottom-space'
|
|
132
|
-
]) {
|
|
133
|
-
expect({ name, value: theme[name] }).toEqual({ name, value: space('large', 20) })
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
for (const name of ['--md-filled-text-field-with-label-top-space', '--md-filled-field-with-label-bottom-space']) {
|
|
137
|
-
expect({ name, value: theme[name] }).toEqual({ name, value: space('large', 34) })
|
|
138
|
-
}
|
|
103
|
+
const fieldSizes = Object.keys(theme).filter(name =>
|
|
104
|
+
/^--md-(outlined|filled)-(text-field|select-text-field|field|select)-.*(space|height|text-size|line-height|populated-size)$/.test(
|
|
105
|
+
name
|
|
106
|
+
)
|
|
107
|
+
)
|
|
139
108
|
|
|
140
|
-
expect(
|
|
109
|
+
expect(fieldSizes).toEqual([])
|
|
110
|
+
/* filter chips keep Material's size on the platform; ox-input-select-buttons sizes its own */
|
|
111
|
+
expect(theme['--md-filter-chip-container-height']).toBeUndefined()
|
|
141
112
|
})
|
|
142
113
|
})
|