Skip to content

Commit ad4a5a1

Browse files
docs(combinator): DLT-3424 bridge logical to physical naming (#1273)
1 parent 344b737 commit ad4a5a1

10 files changed

Lines changed: 110 additions & 37 deletions

File tree

.claude/rules/logical-naming.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,31 @@ onStartClick () {
6969
this.$emit('alpha-clicked');
7070
},
7171
```
72+
73+
## Description Prose
74+
75+
**Identifiers stay logical. Descriptions become bilingual.**
76+
77+
When writing a JSDoc comment, slot description, or doc-page prose that mentions a logical direction, always add the LTR-default physical equivalent as an `(aka <physical>)` parenthetical. This helps consumers mid-migration anchor the logical term to a physical one without requiring them to look it up.
78+
79+
| Logical phrase in description | Bridged form |
80+
|-------------------------------|--------------|
81+
| `block-start side` / `block-start edge` | `block-start side (aka top)` |
82+
| `block-end side` / `block-end edge` | `block-end side (aka bottom)` |
83+
| `inline-start side` / `inline-start edge` | `inline-start side (aka left)` |
84+
| `inline-end side` / `inline-end edge` | `inline-end side (aka right)` |
85+
| `block axis` | `block axis (aka top/bottom)` |
86+
| `inline axis` | `inline axis (aka left/right)` |
87+
88+
Rules:
89+
90+
- Parenthetical is lowercase: `(aka top)` not `(AKA top)`
91+
- Placed inside the sentence, before the period: `side (aka top). Overrides`
92+
- Bridge the first mention in a JSDoc block only — leave subsequent `Overrides …` sentences as-is
93+
- Drop legacy qualifiers: `(top/bottom in horizontal writing mode)``(aka top/bottom)`, `in LTR` → delete
94+
95+
## Combinator Filter
96+
97+
The Combinator prop/slot search uses `packages/combinator/src/lib/logical_aliases.js` as its canonical alias map. In `option_bar.vue`, `tokenizeName` splits each prop/slot name on camelCase boundaries and recognizes compound tokens (`block-start`, `inline-end`, etc.) derived from the alias map keys. `getSearchCorpus` expands those tokens via `logical_aliases.js` to build a precomputed search corpus. `filterCorpora` matches the user's query against that corpus. Searching `"top"` finds `borderWidthBlockStart`, `paddingBlockStart`, etc. automatically.
98+
99+
**When adding new logical-naming vocabulary** (e.g. a new axis concept beyond `block`/`inline`), add the new token and its physical aliases to `logical_aliases.js`. No per-component or per-prop changes needed — the filter picks it up automatically for any component that uses the new token in its prop/slot names.

apps/dialtone-documentation/docs/components/prose.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ Unordered and ordered lists can be freely nested inside each other, with each le
205205

206206
### Blockquote
207207

208-
Blockquotes are visually offset with an inline-start border and muted color, supporting multi-paragraph content, nesting, and attributed citations.
208+
Blockquotes are visually offset with an inline-start (aka left) border and muted color, supporting multi-paragraph content, nesting, and attributed citations.
209209

210210
```vue demo
211211
<!-- @wrapper -->

apps/dialtone-documentation/docs/components/scrollbar.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ In addition to using directive arguments for scrollbar visibility (`:always`, `:
137137
| --- | --- | --- | --- |
138138
| `showScrollbar` | `'enter' \| 'always' \| 'scroll' \| 'move'` | `'enter'` | Scrollbar visibility mode |
139139
| `offset` | `Object` | `null` | Offset configuration for scrollbar positioning |
140-
| `offset.blockStart` | `number \| string` | `undefined` | Insets vertical scrollbar from the block-start edge |
141-
| `offset.blockEnd` | `number \| string` | `undefined` | Insets horizontal scrollbar from the block-end edge |
142-
| `offset.inlineStart` | `number \| string` | `undefined` | Insets horizontal scrollbar from the inline-start edge |
143-
| `offset.inlineEnd` | `number \| string` | `undefined` | Insets vertical scrollbar from the inline-end edge |
140+
| `offset.blockStart` | `number \| string` | `undefined` | Insets vertical scrollbar from the block-start (aka top) edge |
141+
| `offset.blockEnd` | `number \| string` | `undefined` | Insets horizontal scrollbar from the block-end (aka bottom) edge |
142+
| `offset.inlineStart` | `number \| string` | `undefined` | Insets horizontal scrollbar from the inline-start (aka left) edge |
143+
| `offset.inlineEnd` | `number \| string` | `undefined` | Insets vertical scrollbar from the inline-end (aka right) edge |
144144
| `blockClasses` | `string` | `undefined` | CSS classes to apply to the vertical scrollbar |
145145
| `inlineClasses` | `string` | `undefined` | CSS classes to apply to the horizontal scrollbar |
146146

@@ -162,10 +162,10 @@ The `offset` option allows you to adjust the positioning of scrollbars to accomm
162162

163163
| Property | Type | Description |
164164
| --- | --- | --- |
165-
| `blockStart` | `number \| string` | Insets vertical scrollbar from the block-start edge |
166-
| `blockEnd` | `number \| string` | Insets horizontal scrollbar from the block-end edge |
167-
| `inlineStart` | `number \| string` | Insets horizontal scrollbar from the inline-start edge |
168-
| `inlineEnd` | `number \| string` | Insets vertical scrollbar from the inline-end edge |
165+
| `blockStart` | `number \| string` | Insets vertical scrollbar from the block-start (aka top) edge |
166+
| `blockEnd` | `number \| string` | Insets horizontal scrollbar from the block-end (aka bottom) edge |
167+
| `inlineStart` | `number \| string` | Insets horizontal scrollbar from the inline-start (aka left) edge |
168+
| `inlineEnd` | `number \| string` | Insets vertical scrollbar from the inline-end (aka right) edge |
169169

170170
#### Numeric Values (Auto-converted to px)
171171

apps/dialtone-documentation/docs/utilities/spacing/margin.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ keywords: ["outer spacing", "gap", "offset", "margin inline start", "margin inli
88
>
99
> Avoid applying margins directly. Lean toward using layout components like [Stack](/components/stack/) for consistent and maintainable spacing **between** elements.
1010
11-
Use `d-m-{stop}` to set margin using spacing token stops. The number references the spacing token (`d-m-100` = `--dt-spacing-100` = 8px). Logical property aliases are also available: `d-mbs-{stop}` (margin-block-start), `d-mbe-{stop}` (margin-block-end), `d-mis-{stop}` (margin-inline-start), `d-mie-{stop}` (margin-inline-end).
11+
Use `d-m-{stop}` to set margin using spacing token stops. The number references the spacing token (`d-m-100` = `--dt-spacing-100` = 8px). Logical property aliases are also available: `d-mbs-{stop}` (margin-block-start, aka top), `d-mbe-{stop}` (margin-block-end, aka bottom), `d-mis-{stop}` (margin-inline-start, aka left), `d-mie-{stop}` (margin-inline-end, aka right).
1212

1313
## Add Margin to All Sides
1414

@@ -67,7 +67,7 @@ Auto margins allow an element to fill a remaining space within an object. This i
6767

6868
## Classes
6969

70-
Margins can be added using `d-m-{stop}` or directional classes like `d-m{t|r|b|l|y|x}-{stop}`. Logical property aliases are also available: `d-mbs-{stop}` (margin-block-start), `d-mbe-{stop}` (margin-block-end), `d-mis-{stop}` (margin-inline-start), `d-mie-{stop}` (margin-inline-end).
70+
Margins can be added using `d-m-{stop}` or directional classes like `d-m{t|r|b|l|y|x}-{stop}`. Logical property aliases are also available: `d-mbs-{stop}` (margin-block-start, aka top), `d-mbe-{stop}` (margin-block-end, aka bottom), `d-mis-{stop}` (margin-inline-start, aka left), `d-mie-{stop}` (margin-inline-end, aka right).
7171

7272
It is highly recommended to use the [DtStack component](/components/stack.md) prior to applying margins individually.
7373

apps/dialtone-documentation/docs/utilities/spacing/padding.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Use `d-p-{stop}` to set padding using spacing token stops. The number references
4747

4848
## Classes
4949

50-
Padding can be added to an element by using `d-p-{stop}` or a directional class like `d-p{t|r|b|l|y|x}-{stop}`. Logical property aliases are also available: `d-pbs-{stop}` (padding-block-start), `d-pbe-{stop}` (padding-block-end), `d-pis-{stop}` (padding-inline-start), `d-pie-{stop}` (padding-inline-end).
50+
Padding can be added to an element by using `d-p-{stop}` or a directional class like `d-p{t|r|b|l|y|x}-{stop}`. Logical property aliases are also available: `d-pbs-{stop}` (padding-block-start, aka top), `d-pbe-{stop}` (padding-block-end, aka bottom), `d-pis-{stop}` (padding-inline-start, aka left), `d-pie-{stop}` (padding-inline-end, aka right).
5151

5252
It is highly recommended to use the [DtBox component](/components/box.md) before applying padding individually.
5353

packages/combinator/src/components/option_bar/option_bar.vue

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ import { computed, ref, nextTick } from 'vue';
139139
import { OPTIONS_UPDATE_EVENT } from '@/src/lib/constants';
140140
import { getControlByMemberType, getControlByValue } from '@/src/lib/control';
141141
import { isIconSlot } from '@/src/lib/icons';
142+
import { LOGICAL_ALIASES } from '@/src/lib/logical_aliases';
142143
import { DtStack, DtTabGroup, DtTab, DtTabPanel } from '@dialpad/dialtone-vue';
143144
import { DtIconSearch } from '@dialpad/dialtone-icons/vue';
144145
@@ -186,14 +187,42 @@ function normalizeForSearch (str) {
186187
return str.toLowerCase().replace(/[\s\-_]/g, '');
187188
}
188189
189-
function filterMembers (members) {
190+
// Derived from LOGICAL_ALIASES keys so tokenizeName stays in sync automatically.
191+
const COMPOUND_TOKENS = new Set(Object.keys(LOGICAL_ALIASES).filter(k => k.includes('-')));
192+
193+
function tokenizeName (name) {
194+
const parts = name.replace(/([A-Z])/g, ' $1').trim().toLowerCase().split(/\s+/);
195+
const tokens = [];
196+
for (let i = 0; i < parts.length; i++) {
197+
const compound = parts[i + 1] ? `${parts[i]}-${parts[i + 1]}` : null;
198+
if (compound && COMPOUND_TOKENS.has(compound)) {
199+
tokens.push(compound);
200+
i++;
201+
} else {
202+
tokens.push(parts[i]);
203+
}
204+
}
205+
return tokens;
206+
}
207+
208+
function getSearchCorpus (name) {
209+
const tokens = tokenizeName(name);
210+
const aliases = tokens.flatMap(t => LOGICAL_ALIASES[t] ?? []);
211+
return [name, ...tokens, ...aliases].map(normalizeForSearch).join(' ');
212+
}
213+
214+
// Pre-compute corpora once per member list so per-keystroke filtering is just a substring scan.
215+
const propCorpora = computed(() => (props.info.props ?? []).map(m => ({ member: m, corpus: getSearchCorpus(m.name) })));
216+
const slotCorpora = computed(() => (props.info.slots ?? []).map(m => ({ member: m, corpus: getSearchCorpus(m.name) })));
217+
218+
function filterCorpora (corpora) {
190219
const q = normalizeForSearch(searchQuery.value);
191-
if (q.length < 2) return members;
192-
return members.filter(m => normalizeForSearch(m.name).includes(q));
220+
if (q.length < 2) return corpora.map(({ member }) => member);
221+
return corpora.filter(({ corpus }) => corpus.includes(q)).map(({ member }) => member);
193222
}
194223
195-
const filteredProps = computed(() => filterMembers(props.info.props));
196-
const filteredSlots = computed(() => filterMembers(props.info.slots));
224+
const filteredProps = computed(() => filterCorpora(propCorpora.value));
225+
const filteredSlots = computed(() => filterCorpora(slotCorpora.value));
197226
198227
/**
199228
* Gets an array of controls for a binding.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Maps logical CSS naming tokens to their LTR-default physical aliases.
2+
// Used by option_bar.vue so consumers can search "top", "bottom", "left", "right",
3+
// "vertical", or "horizontal" and find logical-named props and slots.
4+
//
5+
// Each entry must be self-contained: a compound key like 'block-start' must list
6+
// every alias a *BlockStart prop should match. The tokenizer does NOT fall back
7+
// to the base 'block' entry — that would bleed opposite-edge aliases ('bottom')
8+
// into block-start results.
9+
export const LOGICAL_ALIASES = {
10+
'block-start': ['top', 'vertical'],
11+
'block-end': ['bottom', 'vertical'],
12+
'inline-start': ['left', 'horizontal'],
13+
'inline-end': ['right', 'horizontal'],
14+
block: ['top', 'bottom', 'vertical'],
15+
inline: ['left', 'right', 'horizontal'],
16+
};

packages/dialtone-vue/components/Box/Box.vue

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,42 +85,42 @@ const props = defineProps({
8585
borderWidth: { type: String, default: undefined, validator: borderWidthValidator },
8686
8787
/**
88-
* Border width on the block axis (top/bottom in horizontal writing mode).
88+
* Border width on the block axis (aka top/bottom).
8989
* Overrides `borderWidth` for block sides.
9090
* @values 0, 50, 100, 150, 200, 300, 400
9191
*/
9292
borderWidthBlock: { type: String, default: undefined, validator: borderWidthValidator },
9393
9494
/**
95-
* Border width on the block-end side.
95+
* Border width on the block-end side (aka bottom).
9696
* Overrides `borderWidthBlock` and `borderWidth` for block-end.
9797
* @values 0, 50, 100, 150, 200, 300, 400
9898
*/
9999
borderWidthBlockEnd: { type: String, default: undefined, validator: borderWidthValidator },
100100
101101
/**
102-
* Border width on the block-start side.
102+
* Border width on the block-start side (aka top).
103103
* Overrides `borderWidthBlock` and `borderWidth` for block-start.
104104
* @values 0, 50, 100, 150, 200, 300, 400
105105
*/
106106
borderWidthBlockStart: { type: String, default: undefined, validator: borderWidthValidator },
107107
108108
/**
109-
* Border width on the inline axis (left/right in LTR).
109+
* Border width on the inline axis (aka left/right).
110110
* Overrides `borderWidth` for inline sides.
111111
* @values 0, 50, 100, 150, 200, 300, 400
112112
*/
113113
borderWidthInline: { type: String, default: undefined, validator: borderWidthValidator },
114114
115115
/**
116-
* Border width on the inline-end side.
116+
* Border width on the inline-end side (aka right).
117117
* Overrides `borderWidthInline` and `borderWidth` for inline-end.
118118
* @values 0, 50, 100, 150, 200, 300, 400
119119
*/
120120
borderWidthInlineEnd: { type: String, default: undefined, validator: borderWidthValidator },
121121
122122
/**
123-
* Border width on the inline-start side.
123+
* Border width on the inline-start side (aka left).
124124
* Overrides `borderWidthInline` and `borderWidth` for inline-start.
125125
* @values 0, 50, 100, 150, 200, 300, 400
126126
*/
@@ -133,55 +133,55 @@ const props = defineProps({
133133
padding: { type: String, default: undefined, validator: spacingValidator },
134134
135135
/**
136-
* Padding on the block axis (top/bottom in horizontal writing mode).
136+
* Padding on the block axis (aka top/bottom).
137137
* Overrides `padding` for the block axis.
138138
* @values 0, 1, 25, 50, 75, 100, 125, 150, 175, 200, 250, 300, 350, 400, 450, 500, 525, 550, 600, 650, 700, 750, 800
139139
*/
140140
paddingBlock: { type: String, default: undefined, validator: spacingValidator },
141141
142142
/**
143-
* Padding on the block-end side.
143+
* Padding on the block-end side (aka bottom).
144144
* Overrides `paddingBlock` and `padding` for block-end.
145145
* @values 0, 1, 25, 50, 75, 100, 125, 150, 175, 200, 250, 300, 350, 400, 450, 500, 525, 550, 600, 650, 700, 750, 800
146146
*/
147147
paddingBlockEnd: { type: String, default: undefined, validator: spacingValidator },
148148
149149
/**
150-
* Padding on the block-start side.
150+
* Padding on the block-start side (aka top).
151151
* Overrides `paddingBlock` and `padding` for block-start.
152152
* @values 0, 1, 25, 50, 75, 100, 125, 150, 175, 200, 250, 300, 350, 400, 450, 500, 525, 550, 600, 650, 700, 750, 800
153153
*/
154154
paddingBlockStart: { type: String, default: undefined, validator: spacingValidator },
155155
156156
/**
157-
* Padding on the inline axis (left/right in LTR).
157+
* Padding on the inline axis (aka left/right).
158158
* Overrides `padding` for the inline axis.
159159
* @values 0, 1, 25, 50, 75, 100, 125, 150, 175, 200, 250, 300, 350, 400, 450, 500, 525, 550, 600, 650, 700, 750, 800
160160
*/
161161
paddingInline: { type: String, default: undefined, validator: spacingValidator },
162162
163163
/**
164-
* Padding on the inline-end side.
164+
* Padding on the inline-end side (aka right).
165165
* Overrides `paddingInline` and `padding` for inline-end.
166166
* @values 0, 1, 25, 50, 75, 100, 125, 150, 175, 200, 250, 300, 350, 400, 450, 500, 525, 550, 600, 650, 700, 750, 800
167167
*/
168168
paddingInlineEnd: { type: String, default: undefined, validator: spacingValidator },
169169
170170
/**
171-
* Padding on the inline-start side.
171+
* Padding on the inline-start side (aka left).
172172
* Overrides `paddingInline` and `padding` for inline-start.
173173
* @values 0, 1, 25, 50, 75, 100, 125, 150, 175, 200, 250, 300, 350, 400, 450, 500, 525, 550, 600, 650, 700, 750, 800
174174
*/
175175
paddingInlineStart: { type: String, default: undefined, validator: spacingValidator },
176176
177177
/**
178-
* Block size (height in horizontal writing mode). Maps to --dt-layout-* tokens.
178+
* Block size (aka height). Maps to --dt-layout-* tokens.
179179
* @values 0, 1px, 2px, 8px, 25, 20px, 24px, 50, 75, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 10p, 20p, 25p, 30p, 33p, 40p, 50p, 60p, 66p, 70p, 75p, 80p, 90p, 95p, 100p
180180
*/
181181
blockSize: { type: String, default: undefined, validator: layoutValidator },
182182
183183
/**
184-
* Inline size (width in horizontal writing mode). Maps to --dt-layout-* tokens.
184+
* Inline size (aka width). Maps to --dt-layout-* tokens.
185185
* @values 0, 1px, 2px, 8px, 25, 20px, 24px, 50, 75, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 10p, 20p, 25p, 30p, 33p, 40p, 50p, 60p, 66p, 70p, 75p, 80p, 90p, 95p, 100p
186186
*/
187187
inlineSize: { type: String, default: undefined, validator: layoutValidator },

packages/dialtone-vue/components/Button/Button.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
startIconClass,
5858
]"
5959
>
60-
<!-- @slot Icon displayed at the start (left in LTR) of the button -->
60+
<!-- @slot Icon displayed at the start (aka left) of the button -->
6161
<slot
6262
name="startIcon"
6363
:icon-size="iconSize"
@@ -107,7 +107,7 @@
107107
endIconClass,
108108
]"
109109
>
110-
<!-- @slot Icon displayed at the end (right in LTR) of the button -->
110+
<!-- @slot Icon displayed at the end (aka right) of the button -->
111111
<slot
112112
name="endIcon"
113113
:icon-size="iconSize"
@@ -334,15 +334,15 @@ export default {
334334
},
335335
336336
/**
337-
* Used to customize the block-start icon container
337+
* Used to customize the block-start (aka top) icon container
338338
*/
339339
blockStartIconClass: {
340340
type: [String, Array, Object],
341341
default: '',
342342
},
343343
344344
/**
345-
* Used to customize the block-end icon container
345+
* Used to customize the block-end (aka bottom) icon container
346346
*/
347347
blockEndIconClass: {
348348
type: [String, Array, Object],

packages/dialtone-vue/components/ItemLayout/ItemLayout.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,15 @@ export default {
158158
},
159159
160160
/**
161-
* Set the class for the block-end section.
161+
* Set the class for the block-end section (aka bottom).
162162
*/
163163
blockEndClass: {
164164
type: [String, Array, Object],
165165
default: '',
166166
},
167167
168168
/**
169-
* Set the class for the block-end section.
169+
* Set the class for the block-end section (aka bottom).
170170
* @deprecated Use blockEndClass
171171
*/
172172
bottomClass: {

0 commit comments

Comments
 (0)