diff --git a/AI.yaml b/AI.yaml index 3624b9f..881fcf2 100644 --- a/AI.yaml +++ b/AI.yaml @@ -11,13 +11,14 @@ rules: - Prefer framework directives ($if, $bind, $onclick, slots) and Bootstrap classes over imperative page setup or custom CSS. Keep test actions limited to assertions and interaction verification. - Test pages use full-height flex layouts: the component area fills remaining space and result output is a bounded, internally scrollable region. - The outer test console keeps the selected test active and represents pass/fail with a visible status badge; detailed output belongs inside the selected test page. - - Public source and YAML use the same PascalCase basename (for example `components/List.js` and `components/List.yaml`, `frameworks/State.js` and `frameworks/State.yaml`). + - Public source and YAML use the same PascalCase basename (for example `components/base/List.js` and `components/base/List.yaml`, `frameworks/State.js` and `frameworks/State.yaml`). loading: - example: '' + example: '' rules: - Load ui.js in head without async, defer, or type="module". - Always write components with every public component used by the page. + - Use `base` or `form` to load the documented component category; individual names and category names can be mixed. - Do not list utilities or framework dependencies. - ui.js loads frameworks/State.js and frameworks/Bootstrap.js beside itself. - npm run build writes source modification versions into ui.js; ui.min.js loads matching adjacent .min.js files. @@ -27,20 +28,20 @@ framework: - frameworks/Bootstrap.yaml components: - - components/API.yaml - - components/AutoForm.yaml - - components/List.yaml - - components/Modal.yaml - - components/Dialog.yaml - - components/Toast.yaml - - components/Nav.yaml - - components/Resizer.yaml + - components/base/API.yaml + - components/base/AutoForm.yaml + - components/base/List.yaml + - components/base/Modal.yaml + - components/base/Dialog.yaml + - components/base/Toast.yaml + - components/base/Nav.yaml + - components/base/Resizer.yaml - components/form/DatePicker.yaml - components/form/ColorPicker.yaml - components/form/IconPicker.yaml - components/form/TagsInput.yaml - - components/DataTable.yaml - - components/DataChart.yaml + - components/data/DataGrid.yaml + - components/data/Chart.yaml utilities: - utilities/HTTP.yaml diff --git a/README.md b/README.md index 1542e12..6ddf133 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ Pages load `ui.js` directly from a CDN and explicitly declare required public APIs: ```html - + ``` -`ui.js` always loads every file in `frameworks/` and `utilities/`. The `components` attribute only lists public components used by the page. +`ui.js` always loads every file in `frameworks/` and `utilities/`. The `components` attribute accepts public component names and the `base` and `form` categories; both forms can be mixed. Load `ui.js` in `` as a normal script. Do not use `async`, `defer`, or `type="module"`: it writes the requested classic scripts into the parser stream so state can scan the complete DOM at `DOMContentLoaded` before first render. diff --git a/README.zh-CN.md b/README.zh-CN.md index 2580d36..a21631c 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -5,7 +5,7 @@ `@apigo.cc/ui` 是不需要生产构建的原生 JavaScript UI 组件库。页面使用一个 `ui.js` 入口,并且每个页面都显式写出使用的组件: ```html - + ``` `ui.js` 默认加载 `frameworks/` 和底层 `utilities/`。`components` 中只填写页面直接使用的公开组件名,例如 `components="List,AutoForm,Resizer"`;组件依赖会自动加载,不需要填写 state、bootstrap、HTTP、VirtualScroll 或 MouseMover。 diff --git a/components/DataTable.yaml b/components/DataTable.yaml deleted file mode 100644 index deb644a..0000000 --- a/components/DataTable.yaml +++ /dev/null @@ -1,76 +0,0 @@ -name: DataTable - -attributes: - editable: - type: boolean - behavior: Enable row, field, cell, and save controls. - -state: - fields: Array of column definitions; assign before list. - list: Array of row objects; each key matches a field id. - _originalList: Internal unfiltered row snapshot. - sortConfig: "{ fieldId, direction }" - filterConfig: Per-field filter configuration. - selectedRowCount: Selected row count. - isDirty: Whether edits are pending save. - -field: - required: [id, name] - fields: - id: Unique column id and row value key. - name: Header label. - type: Source value type. - memo: Field description. - settings: "{ width, pinned, formType, options, decimals, prefix, suffix, thousandSep, labelOn, labelOff }" - formatter: Function receiving value and field. - -methods: - addRow: Add an empty row. - deleteSelectedRow: Delete selected rows. - saveChanges: Dispatch save. - addField: Add a field. - editField: Edit the active field. - deleteField: Delete the active field. - editCell: Open a cell editor. - applySortFilter: Apply current or supplied sorting and filters. - -events: - save: - detail: "{ list, fields }" - savefields: - detail: fields - remove: - detail: "{ items }" - -global: - DataTable: - methods: - registerFieldType: Register a field type configuration. - getFieldTypes: Return registered field types. - -related: - - AutoForm.yaml - - ../utilities/VirtualScroll.yaml - - Resizer.yaml - -rules: - - Bind fields and list with $.state.fields and $.state.list. - - Treat underscore-prefixed state fields as internal read-only diagnostics. - - Custom field editors must be registered in AutoForm before use. - -example: | - - - -tests: - - apigo.cc/web/dataTable/test/all.spec.js - - apigo.cc/web/dataTable/test/correctness.spec.js - - apigo.cc/web/dataTable/test/validation.spec.js diff --git a/components/Dialog.min.js b/components/Dialog.min.js deleted file mode 100644 index a645664..0000000 --- a/components/Dialog.min.js +++ /dev/null @@ -1 +0,0 @@ -globalThis.Component.register("Dialog",globalThis.Component.getSetupFunction("Modal"),globalThis.Util.makeDom('\n\n'));let _dialogCount=0;globalThis.Dialog={show({title:t="",message:e="",buttons:s=["{#Close#}"],type:a="body"}){const o=document.body.appendChild(document.createElement("Dialog"));return o.style.zIndex=2e3+ ++_dialogCount,Promise.resolve().then(()=>{Object.assign(o.state,{message:e,title:t,type:a,buttons:s}),o.show()}),new Promise(t=>{o.addEventListener("change",e=>{_dialogCount--,t(o.result||0),o.remove()})})},alert(t,e={}){return this.show({message:t,...e})},confirm(t,e={}){return new Promise(s=>this.show({message:t,buttons:["{#Cancel#}","{#Confirm#}"],...e}).then(t=>s(t>=2)).catch(()=>s(!1)))}}; diff --git a/components/Modal.min.js b/components/Modal.min.js deleted file mode 100644 index 123e558..0000000 --- a/components/Modal.min.js +++ /dev/null @@ -1 +0,0 @@ -globalThis.Component.register("Modal",t=>{t.modal=new bootstrap.Modal(t),t.addEventListener("bind",d=>{d.detail?t.modal.show():t.modal.hide()}),t.addEventListener("hide.bs.modal",()=>{document.activeElement?.blur(),t.dispatchEvent(new CustomEvent("change",{bubbles:!1,detail:!1}))}),globalThis.Util.copyFunction(t,t.modal,"show","hide")},globalThis.Util.makeDom('\n\n')); diff --git a/components/Nav.yaml b/components/Nav.yaml deleted file mode 100644 index 8265124..0000000 --- a/components/Nav.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: Nav - -attributes: - vertical: - type: boolean - -state: - brand: "{ image?, icon?, label? }" - list: Array of navigation item objects; assign `nav.state.list = items`. - value: Selected item `name`. - openName: Open dropdown name in vertical mode. - -item_types: - label: Non-clickable text. - button: Selectable navigation item. - dropdown: Group of label, button, or switch items. - fill: Horizontal spacer item. - -events: - change: - detail: Selected item name. - nav: - detail: '{ item } or { item, open } for vertical dropdown changes.' - -item_shape: "{ type, name, label, icon?, items? }" - -examples: - - EXAMPLE/Nav/Basic.yaml - - EXAMPLE/Nav/Dropdown.yaml - -example: EXAMPLE/Nav/Basic.yaml diff --git a/components/Nav/Basic.yaml b/components/Nav/Basic.yaml deleted file mode 100644 index 6cfb7a9..0000000 --- a/components/Nav/Basic.yaml +++ /dev/null @@ -1,11 +0,0 @@ -purpose: Basic navigation. - -code: | - - -data: | - const nav = document.querySelector('#mainNav') - nav.state.list = [ - { type: 'button', name: 'home', label: 'Home', icon: 'house' }, - { type: 'button', name: 'settings', label: 'Settings', icon: 'gear' } - ] diff --git a/components/Nav/Dropdown.yaml b/components/Nav/Dropdown.yaml deleted file mode 100644 index b76646c..0000000 --- a/components/Nav/Dropdown.yaml +++ /dev/null @@ -1,15 +0,0 @@ -purpose: Navigation with a dropdown and a listener for selection. - -code: | - - diff --git a/components/API.js b/components/base/API.js similarity index 100% rename from components/API.js rename to components/base/API.js diff --git a/components/API.min.js b/components/base/API.min.js similarity index 100% rename from components/API.min.js rename to components/base/API.min.js diff --git a/components/API.test.html b/components/base/API.test.html similarity index 98% rename from components/API.test.html rename to components/base/API.test.html index da9352a..92fad26 100644 --- a/components/API.test.html +++ b/components/base/API.test.html @@ -3,7 +3,7 @@ components.API tests - + + + +
+

components.Dialog

未测试

+
diff --git a/components/Dialog.yaml b/components/base/Dialog.yaml similarity index 100% rename from components/Dialog.yaml rename to components/base/Dialog.yaml diff --git a/components/List.js b/components/base/List.js similarity index 100% rename from components/List.js rename to components/base/List.js diff --git a/components/List.min.js b/components/base/List.min.js similarity index 100% rename from components/List.min.js rename to components/base/List.min.js diff --git a/components/List.test.html b/components/base/List.test.html similarity index 99% rename from components/List.test.html rename to components/base/List.test.html index 733e206..6c7caa3 100644 --- a/components/List.test.html +++ b/components/base/List.test.html @@ -4,7 +4,7 @@ components.List tests - + + + + +
+

components.Modal

未测试
+
Custom header
Custom body
Custom footer
+

+  
+ + + diff --git a/components/Modal.yaml b/components/base/Modal.yaml similarity index 100% rename from components/Modal.yaml rename to components/base/Modal.yaml diff --git a/components/Nav.js b/components/base/Nav.js similarity index 94% rename from components/Nav.js rename to components/base/Nav.js index dd3f90f..5dd43ec 100644 --- a/components/Nav.js +++ b/components/base/Nav.js @@ -61,12 +61,12 @@ globalThis.Component.register('Nav', container => {