nwl-components 1.5.3 → 1.6.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 CHANGED
@@ -103,6 +103,53 @@ panel (for example a long project name with no spaces), opts in with the class
103
103
  </tr>
104
104
  ```
105
105
 
106
+ ### Tables without Vue
107
+
108
+ Pages that build their tables with template strings and the DOM sort them the same way
109
+ with `nwl-components/sort`, which has no Vue (about 3 kB). Importing these names from
110
+ `nwl-components` itself also works, but bundles Vue and the whole library.
111
+ `useSortable` and `SortableTh` use the same code, so the order and the header markup
112
+ never differ.
113
+
114
+ ```js
115
+ import { nextSort, sortRows, sortableHeader } from 'nwl-components/sort';
116
+
117
+ const columns = { Name: { key: 'project' }, Files: { key: 'numFiles', type: 'number' } };
118
+ let state = { column: null, ascending: true };
119
+ const headers = {};
120
+ const render = () => {
121
+ const rows = state.column ? sortRows(projects, columns[state.column], state.ascending) : projects;
122
+ tbody.innerHTML = rows.map((p) => `<tr><td>${p.project}</td><td>${p.numFiles}</td></tr>`).join('');
123
+ for (const [name, header] of Object.entries(headers)) {
124
+ header.setDirection(name !== state.column ? 'none' : state.ascending ? 'ascending' : 'descending');
125
+ }
126
+ };
127
+ for (const th of table.querySelectorAll('th')) {
128
+ const name = th.textContent;
129
+ headers[name] = sortableHeader(th, { onSort: () => { state = nextSort(state, name); render(); } });
130
+ }
131
+ render();
132
+ ```
133
+
134
+ - `sortRows(rows, { key, type }, ascending = true)`: a new, sorted array (stable; missing
135
+ values last in both directions; strings in natural order, `localeCompare` with
136
+ `numeric: true`, so "E90" comes before "E120"; since 1.6.1). `sortValue(row, column)`
137
+ is the value it compares.
138
+ - `sortableHeader(th, { direction, onSort })` turns a `<th>` into SortableTh's markup
139
+ (`class="nwl-sortable"`, `aria-sort`, a `<button type="button">` with the th's content
140
+ and the icon; Enter and Space work as on any button) and returns
141
+ `{ th, button, setDirection(direction) }`.
142
+ - `nextSort(state, column)`: the sort after a click, as in `useSortable`.
143
+ - For template strings: `renderSortIcon(direction)` (the SVG) and `ariaSort(direction)`.
144
+
145
+ The headers' look is in `nwl-components/sort/style.css`, which has only the
146
+ `th.nwl-sortable` and `.nwl-sort-*` rules (1 kB). Load that file, not `dist/style.css`, on a
147
+ page not built with nwl-components: `dist/style.css` has global rules (`*` sets the font
148
+ size and colour of every element). With a bundler, `import 'nwl-components/sort/style.css'`
149
+ (webpack 4 included); otherwise link `node_modules/nwl-components/dist/sort/style.css`.
150
+ `dist/style.css` keeps the same rules for `SortableTh`. Story: `Common/PlainSort`.
151
+ Since 1.6.0.
152
+
106
153
  ## Single File Components
107
154
 
108
155
  This project makes use of Vue SFCs: _Single File Components_, that have the `.vue` extension.