react-cheminfo 0.6.0 → 0.7.0

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.
Files changed (79) hide show
  1. package/README.md +16 -0
  2. package/lib/citation/core/index.d.ts +1 -0
  3. package/lib/citation/core/index.d.ts.map +1 -1
  4. package/lib/citation/core/index.js +1 -0
  5. package/lib/citation/core/index.js.map +1 -1
  6. package/lib/citation/core/platformPaper.d.ts +14 -0
  7. package/lib/citation/core/platformPaper.d.ts.map +1 -0
  8. package/lib/citation/core/platformPaper.js +28 -0
  9. package/lib/citation/core/platformPaper.js.map +1 -0
  10. package/lib/color/core/index.d.ts +1 -1
  11. package/lib/color/core/index.d.ts.map +1 -1
  12. package/lib/color/core/index.js +1 -1
  13. package/lib/color/core/index.js.map +1 -1
  14. package/lib/core.d.ts +1 -0
  15. package/lib/core.d.ts.map +1 -1
  16. package/lib/core.js +1 -0
  17. package/lib/core.js.map +1 -1
  18. package/lib/ecosystem/core/sites.js +5 -5
  19. package/lib/orbital/core/index.d.ts +1 -1
  20. package/lib/orbital/core/index.d.ts.map +1 -1
  21. package/lib/orbital/core/index.js +1 -1
  22. package/lib/orbital/core/index.js.map +1 -1
  23. package/lib/periodic/core/categories.d.ts +25 -0
  24. package/lib/periodic/core/categories.d.ts.map +1 -0
  25. package/lib/periodic/core/categories.js +70 -0
  26. package/lib/periodic/core/categories.js.map +1 -0
  27. package/lib/periodic/core/elements.d.ts +49 -0
  28. package/lib/periodic/core/elements.d.ts.map +1 -0
  29. package/lib/periodic/core/elements.js +175 -0
  30. package/lib/periodic/core/elements.js.map +1 -0
  31. package/lib/periodic/core/index.d.ts +6 -0
  32. package/lib/periodic/core/index.d.ts.map +1 -0
  33. package/lib/periodic/core/index.js +4 -0
  34. package/lib/periodic/core/index.js.map +1 -0
  35. package/lib/periodic/core/layout.d.ts +73 -0
  36. package/lib/periodic/core/layout.d.ts.map +1 -0
  37. package/lib/periodic/core/layout.js +132 -0
  38. package/lib/periodic/core/layout.js.map +1 -0
  39. package/lib/periodic/ui/CategoryLegend.d.ts +26 -0
  40. package/lib/periodic/ui/CategoryLegend.d.ts.map +1 -0
  41. package/lib/periodic/ui/CategoryLegend.js +53 -0
  42. package/lib/periodic/ui/CategoryLegend.js.map +1 -0
  43. package/lib/periodic/ui/ElementCell.d.ts +53 -0
  44. package/lib/periodic/ui/ElementCell.d.ts.map +1 -0
  45. package/lib/periodic/ui/ElementCell.js +56 -0
  46. package/lib/periodic/ui/ElementCell.js.map +1 -0
  47. package/lib/periodic/ui/PeriodicTable.d.ts +90 -0
  48. package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -0
  49. package/lib/periodic/ui/PeriodicTable.js +77 -0
  50. package/lib/periodic/ui/PeriodicTable.js.map +1 -0
  51. package/lib/periodic/ui/PeriodicTableChrome.d.ts +36 -0
  52. package/lib/periodic/ui/PeriodicTableChrome.d.ts.map +1 -0
  53. package/lib/periodic/ui/PeriodicTableChrome.js +72 -0
  54. package/lib/periodic/ui/PeriodicTableChrome.js.map +1 -0
  55. package/lib/periodic/ui/index.d.ts +7 -0
  56. package/lib/periodic/ui/index.d.ts.map +1 -0
  57. package/lib/periodic/ui/index.js +4 -0
  58. package/lib/periodic/ui/index.js.map +1 -0
  59. package/lib/ui.d.ts +1 -0
  60. package/lib/ui.d.ts.map +1 -1
  61. package/lib/ui.js +1 -0
  62. package/lib/ui.js.map +1 -1
  63. package/package.json +2 -1
  64. package/src/citation/core/index.ts +1 -0
  65. package/src/citation/core/platformPaper.ts +32 -0
  66. package/src/color/core/index.ts +6 -1
  67. package/src/core.ts +1 -0
  68. package/src/ecosystem/core/sites.ts +5 -5
  69. package/src/orbital/core/index.ts +1 -1
  70. package/src/periodic/core/categories.ts +83 -0
  71. package/src/periodic/core/elements.ts +217 -0
  72. package/src/periodic/core/index.ts +27 -0
  73. package/src/periodic/core/layout.ts +183 -0
  74. package/src/periodic/ui/CategoryLegend.tsx +105 -0
  75. package/src/periodic/ui/ElementCell.tsx +137 -0
  76. package/src/periodic/ui/PeriodicTable.tsx +226 -0
  77. package/src/periodic/ui/PeriodicTableChrome.tsx +170 -0
  78. package/src/periodic/ui/index.ts +6 -0
  79. package/src/ui.ts +1 -0
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { COLUMN_COUNT, INNER_TRANSITION_MARKERS, INNER_TRANSITION_ROWS, } from "../core/layout.js";
3
+ /**
4
+ * The 1–18 strip along the top and the 1–7 strip down the left.
5
+ *
6
+ * They are buttons when the table takes a range: "plot period 3" is one click
7
+ * there and eight on the cells.
8
+ * @param props - See {@link HeaderStripsProps}.
9
+ * @returns The two strips, placed on the grid.
10
+ */
11
+ export function HeaderStrips(props) {
12
+ const { onSelectRange } = props;
13
+ const groups = [];
14
+ for (let group = 1; group <= COLUMN_COUNT; group++) {
15
+ groups.push(_jsx(HeaderCell, { label: String(group), title: `Group ${String(group)}`, column: group + 1, row: 1, onClick: onSelectRange &&
16
+ (() => {
17
+ onSelectRange({ kind: 'group', value: group });
18
+ }) }, `group-${String(group)}`));
19
+ }
20
+ const periods = [];
21
+ for (let period = 1; period <= 7; period++) {
22
+ periods.push(_jsx(HeaderCell, { label: String(period), title: `Period ${String(period)}`, column: 1, row: period + 1, onClick: onSelectRange &&
23
+ (() => {
24
+ onSelectRange({ kind: 'period', value: period });
25
+ }) }, `period-${String(period)}`));
26
+ }
27
+ return (_jsxs(_Fragment, { children: [groups, periods, INNER_TRANSITION_ROWS.map(({ row, period }) => (_jsx("div", { style: { ...headerStyle, gridColumn: 1, gridRow: row + 1 }, children: period }, `inner-${String(row)}`)))] }));
28
+ }
29
+ /**
30
+ * The two cells the lanthanoids and the actinoids were lifted out of.
31
+ * @param props - See {@link InnerTransitionMarkersProps}.
32
+ * @returns The markers, placed on the grid.
33
+ */
34
+ export function InnerTransitionMarkers(props) {
35
+ const { offset } = props;
36
+ return (_jsx(_Fragment, { children: INNER_TRANSITION_MARKERS.map(({ cell, label, category }) => (_jsx("div", { "aria-hidden": "true", style: {
37
+ ...markerStyle,
38
+ gridColumn: cell.column + offset,
39
+ gridRow: cell.row + offset,
40
+ }, children: label }, category))) }));
41
+ }
42
+ function HeaderCell(props) {
43
+ const { label, title, column, row, onClick } = props;
44
+ const style = { ...headerStyle, gridColumn: column, gridRow: row };
45
+ if (onClick === undefined)
46
+ return _jsx("div", { style: style, children: label });
47
+ return (_jsx("button", { type: "button", "aria-label": title, onClick: onClick, style: { ...style, ...headerButtonStyle }, children: label }));
48
+ }
49
+ const headerStyle = {
50
+ alignItems: 'center',
51
+ color: 'rgb(95 107 124)',
52
+ display: 'flex',
53
+ fontSize: 'clamp(0.4rem, 1.9cqw, 0.62rem)',
54
+ justifyContent: 'center',
55
+ padding: 0,
56
+ };
57
+ const headerButtonStyle = {
58
+ background: 'none',
59
+ border: 'none',
60
+ cursor: 'pointer',
61
+ font: 'inherit',
62
+ };
63
+ const markerStyle = {
64
+ alignItems: 'center',
65
+ border: '1px dashed rgb(182 191 204)',
66
+ borderRadius: 3,
67
+ color: 'rgb(95 107 124)',
68
+ display: 'flex',
69
+ fontSize: 'clamp(0.36rem, 1.7cqw, 0.55rem)',
70
+ justifyContent: 'center',
71
+ };
72
+ //# sourceMappingURL=PeriodicTableChrome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PeriodicTableChrome.js","sourceRoot":"","sources":["../../../src/periodic/ui/PeriodicTableChrome.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type { CategoryLegendProps } from './CategoryLegend.tsx';
2
+ export { CategoryLegend } from './CategoryLegend.tsx';
3
+ export type { ElementCellProps } from './ElementCell.tsx';
4
+ export { ElementCell } from './ElementCell.tsx';
5
+ export type { PeriodicTableProps } from './PeriodicTable.tsx';
6
+ export { PeriodicTable } from './PeriodicTable.tsx';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/periodic/ui/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { CategoryLegend } from "./CategoryLegend.js";
2
+ export { ElementCell } from "./ElementCell.js";
3
+ export { PeriodicTable } from "./PeriodicTable.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/periodic/ui/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAsB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAqB,CAAC"}
package/lib/ui.d.ts CHANGED
@@ -11,6 +11,7 @@ export * from './error/ui/index.ts';
11
11
  export * from './help/ui/index.ts';
12
12
  export * from './hooks/ui/index.ts';
13
13
  export * from './pedagogy/ui/index.ts';
14
+ export * from './periodic/ui/index.ts';
14
15
  export * from './share/ui/index.ts';
15
16
  export * from './shared/ui/index.ts';
16
17
  export * from './state/ui/index.ts';
package/lib/ui.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
package/lib/ui.js CHANGED
@@ -11,6 +11,7 @@ export * from "./error/ui/index.js";
11
11
  export * from "./help/ui/index.js";
12
12
  export * from "./hooks/ui/index.js";
13
13
  export * from "./pedagogy/ui/index.js";
14
+ export * from "./periodic/ui/index.js";
14
15
  export * from "./share/ui/index.js";
15
16
  export * from "./shared/ui/index.js";
16
17
  export * from "./state/ui/index.js";
package/lib/ui.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-cheminfo",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "license": "MIT",
5
5
  "description": "Assembled React components shared by the cheminfo sites: a Cite button and an ecosystem menu",
6
6
  "author": "Luc Patiny",
@@ -54,6 +54,7 @@
54
54
  "@types/react-dom": "^19.2.4",
55
55
  "@vitest/coverage-v8": "^4.1.10",
56
56
  "@zakodium/tsconfig": "^1.0.5",
57
+ "chemical-elements": "^2.3.2",
57
58
  "eslint": "^9.39.5",
58
59
  "eslint-config-cheminfo-react": "^20.1.0",
59
60
  "eslint-config-cheminfo-typescript": "^22.1.0",
@@ -12,6 +12,7 @@ export {
12
12
  citationFilename,
13
13
  formatCitation,
14
14
  } from './formats.ts';
15
+ export { PLATFORM_PAPER, PLATFORM_WORK } from './platformPaper.ts';
15
16
  export type { Reference, ReferenceAuthor } from './reference.ts';
16
17
  export { doiUrl } from './reference.ts';
17
18
  export type {
@@ -0,0 +1,32 @@
1
+ import type { Reference } from './reference.ts';
2
+ import type { CitedWork } from './works.ts';
3
+
4
+ /**
5
+ * The platform every site of the family runs on: chemical data processed in the
6
+ * browser, which is what makes these applications rather than queues of jobs.
7
+ * One record holds it, so no site can name a different version of it.
8
+ */
9
+ export const PLATFORM_PAPER: Reference = {
10
+ authors: [{ given: 'L.', family: 'Patiny' }],
11
+ title:
12
+ 'Unlocking the Potential of Browser-Based Scientific Data Analysis: A 20-Year Journey of Expertise',
13
+ journal: 'CHIMIA',
14
+ journalAbbreviation: 'Chimia',
15
+ year: 2025,
16
+ volume: '79',
17
+ issue: '1-2',
18
+ firstPage: '66',
19
+ lastPage: '69',
20
+ doi: '10.2533/chimia.2025.66',
21
+ publisher: 'Swiss Chemical Society',
22
+ };
23
+
24
+ /**
25
+ * The platform paper as the second work a site asks to be cited, after the work
26
+ * the tool itself implements.
27
+ */
28
+ export const PLATFORM_WORK: CitedWork = {
29
+ reference: PLATFORM_PAPER,
30
+ what: 'Data processing in the browser',
31
+ note: 'Cite it for the site itself, which runs in the browser.',
32
+ };
@@ -1,4 +1,9 @@
1
1
  export type { ReadableInkOptions } from './contrast.ts';
2
2
  export { contrastRatio, readableInk, relativeLuminance } from './contrast.ts';
3
3
  export type { PositionInRangeOptions, Swatch } from './scale.ts';
4
- export { VIRIDIS_SCALE, positionInRange, swatchFromScale } from './scale.ts';
4
+ export {
5
+ VIRIDIS_SCALE,
6
+ colorFromScale,
7
+ positionInRange,
8
+ swatchFromScale,
9
+ } from './scale.ts';
package/src/core.ts CHANGED
@@ -8,6 +8,7 @@ export * from './ecosystem/core/index.ts';
8
8
  export * from './format/core/index.ts';
9
9
  export * from './orbital/core/index.ts';
10
10
  export * from './pedagogy/core/index.ts';
11
+ export * from './periodic/core/index.ts';
11
12
  export * from './router/core/index.ts';
12
13
  export * from './seo/core/index.ts';
13
14
  export * from './share/core/index.ts';
@@ -107,8 +107,8 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
107
107
  repository: 'https://github.com/cheminfo/chemcalc.org',
108
108
  tagline: 'Molecular formula, exact mass and isotopic distribution.',
109
109
  brand: '#5b52e0',
110
- brandAlt: '#0d9488',
111
- mark: { plate: '#5b52e0', accent: '#09d3ac' },
110
+ brandAlt: '#d63384',
111
+ mark: { plate: '#5b52e0', accent: '#ff8ac2' },
112
112
  },
113
113
  {
114
114
  id: 'nmrium',
@@ -206,9 +206,9 @@ export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
206
206
  host: 'polycarp.cheminfo.org',
207
207
  repository: 'https://github.com/cheminfo/polycarp.cheminfo.org',
208
208
  tagline: 'Predict the microstructure of a radical copolymerisation.',
209
- brand: '#0d1d37',
210
- brandAlt: '#0c9ba3',
211
- mark: { plate: '#0d1d37', accent: '#0c9ba3' },
209
+ brand: '#701a75',
210
+ brandAlt: '#4d7c0f',
211
+ mark: { plate: '#701a75', accent: '#a3e635' },
212
212
  },
213
213
  {
214
214
  id: '3d',
@@ -60,4 +60,4 @@ export type {
60
60
  } from './sample.ts';
61
61
  export { runAtomicSample } from './sample.ts';
62
62
  export type { Screening } from './screening.ts';
63
- export { slaterScreening } from './screening.ts';
63
+ export { groupRank, slaterScreening } from './screening.ts';
@@ -0,0 +1,83 @@
1
+ /**
2
+ * What each family is called, and the colour it takes.
3
+ *
4
+ * Ten hues that stay distinguishable under deuteranopia and protanopia, and
5
+ * that keep the metals warm and the non-metals cool the way a wall chart does.
6
+ * Each is paired at load with the ink that stays readable on it, so a cell
7
+ * never has to compute a contrast while it renders.
8
+ */
9
+
10
+ import { readableInk } from '../../color/core/contrast.ts';
11
+ import type { Swatch } from '../../color/core/scale.ts';
12
+
13
+ import type { ElementCategory } from './elements.ts';
14
+
15
+ /** Families in the order a legend lists them, which is the order of the table. */
16
+ export const CATEGORY_ORDER: readonly ElementCategory[] = [
17
+ 'alkali-metal',
18
+ 'alkaline-earth-metal',
19
+ 'transition-metal',
20
+ 'post-transition-metal',
21
+ 'metalloid',
22
+ 'nonmetal',
23
+ 'halogen',
24
+ 'noble-gas',
25
+ 'lanthanoid',
26
+ 'actinoid',
27
+ ];
28
+
29
+ /** What each family is called in a legend. */
30
+ export const CATEGORY_LABELS: Record<ElementCategory, string> = {
31
+ 'alkali-metal': 'Alkali metal',
32
+ 'alkaline-earth-metal': 'Alkaline earth',
33
+ 'transition-metal': 'Transition metal',
34
+ 'post-transition-metal': 'Post-transition',
35
+ metalloid: 'Metalloid',
36
+ nonmetal: 'Non-metal',
37
+ halogen: 'Halogen',
38
+ 'noble-gas': 'Noble gas',
39
+ lanthanoid: 'Lanthanoid',
40
+ actinoid: 'Actinoid',
41
+ };
42
+
43
+ const CATEGORY_BACKGROUNDS: Record<ElementCategory, string> = {
44
+ 'alkali-metal': '#f4a58a',
45
+ 'alkaline-earth-metal': '#f6c98a',
46
+ 'transition-metal': '#e8b7d4',
47
+ 'post-transition-metal': '#c8c3ea',
48
+ metalloid: '#c9d67c',
49
+ nonmetal: '#7fd4a8',
50
+ halogen: '#8fd9d2',
51
+ 'noble-gas': '#9ec9f0',
52
+ lanthanoid: '#f2d06b',
53
+ actinoid: '#e5a3a3',
54
+ };
55
+
56
+ /** The colour of each family, with the ink that stays readable on it. */
57
+ export const CATEGORY_SWATCHES: Record<ElementCategory, Swatch> =
58
+ Object.fromEntries(
59
+ CATEGORY_ORDER.map((category) => [
60
+ category,
61
+ {
62
+ background: CATEGORY_BACKGROUNDS[category],
63
+ foreground: readableInk(CATEGORY_BACKGROUNDS[category]),
64
+ },
65
+ ]),
66
+ ) as Record<ElementCategory, Swatch>;
67
+
68
+ const UNKNOWN_BACKGROUND = '#e4e8ee';
69
+
70
+ /** Shown for a cell whose family is unknown. */
71
+ export const UNKNOWN_SWATCH: Swatch = {
72
+ background: UNKNOWN_BACKGROUND,
73
+ foreground: readableInk(UNKNOWN_BACKGROUND),
74
+ };
75
+
76
+ /**
77
+ * The swatch of one family.
78
+ * @param category - Family to look up.
79
+ * @returns Its colour and the ink to write on it.
80
+ */
81
+ export function categorySwatch(category: ElementCategory): Swatch {
82
+ return CATEGORY_SWATCHES[category] ?? UNKNOWN_SWATCH;
83
+ }
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Where every element sits in the table, and which family it belongs to.
3
+ *
4
+ * Deliberately the *position* and nothing else: the masses, the isotopes and
5
+ * the exact monoisotopic masses are `chemical-elements`' subject, and a site
6
+ * that needs them reads them from there. Importing that package pulls its whole
7
+ * isotope table, which a site wanting only an element picker must not be made
8
+ * to carry — so the symbols and names are repeated here, and a test asserts
9
+ * they still agree with it.
10
+ *
11
+ * `block` follows the element's *position* in the table, which is what a
12
+ * student reads off it. The configuration is the authority on which subshell is
13
+ * actually filling, and the two disagree for a handful of elements — lanthanum
14
+ * fills 5d, not 4f. See `ELEMENT_ANOMALIES` in the orbital module.
15
+ */
16
+
17
+ /** Region of the table an element sits in. */
18
+ export type ElementBlock = 's' | 'p' | 'd' | 'f';
19
+
20
+ /** Coarse family, used to colour the table. */
21
+ export type ElementCategory =
22
+ | 'alkali-metal'
23
+ | 'alkaline-earth-metal'
24
+ | 'transition-metal'
25
+ | 'post-transition-metal'
26
+ | 'metalloid'
27
+ | 'nonmetal'
28
+ | 'halogen'
29
+ | 'noble-gas'
30
+ | 'lanthanoid'
31
+ | 'actinoid';
32
+
33
+ /** One element, as the table places it. */
34
+ export interface PeriodicElement {
35
+ /** Proton count, 1 to 118. */
36
+ atomicNumber: number;
37
+ /** Chemical symbol, e.g. `Fe`. */
38
+ symbol: string;
39
+ /** English name, spelled as `chemical-elements` spells it. */
40
+ name: string;
41
+ /** Row of the table, 1 to 7. */
42
+ period: number;
43
+ /** IUPAC column 1 to 18; `null` for the lanthanoids and the actinoids. */
44
+ group: number | null;
45
+ block: ElementBlock;
46
+ category: ElementCategory;
47
+ }
48
+
49
+ /** `[symbol, name, period, group, category]`; atomic number is the position. */
50
+ type ElementRow = [string, string, number, number | null, ElementCategory];
51
+
52
+ const ROWS: ElementRow[] = [
53
+ ['H', 'Hydrogen', 1, 1, 'nonmetal'],
54
+ ['He', 'Helium', 1, 18, 'noble-gas'],
55
+ ['Li', 'Lithium', 2, 1, 'alkali-metal'],
56
+ ['Be', 'Beryllium', 2, 2, 'alkaline-earth-metal'],
57
+ ['B', 'Boron', 2, 13, 'metalloid'],
58
+ ['C', 'Carbon', 2, 14, 'nonmetal'],
59
+ ['N', 'Nitrogen', 2, 15, 'nonmetal'],
60
+ ['O', 'Oxygen', 2, 16, 'nonmetal'],
61
+ ['F', 'Fluorine', 2, 17, 'halogen'],
62
+ ['Ne', 'Neon', 2, 18, 'noble-gas'],
63
+ ['Na', 'Sodium', 3, 1, 'alkali-metal'],
64
+ ['Mg', 'Magnesium', 3, 2, 'alkaline-earth-metal'],
65
+ ['Al', 'Aluminium', 3, 13, 'post-transition-metal'],
66
+ ['Si', 'Silicon', 3, 14, 'metalloid'],
67
+ ['P', 'Phosphorus', 3, 15, 'nonmetal'],
68
+ ['S', 'Sulfur', 3, 16, 'nonmetal'],
69
+ ['Cl', 'Chlorine', 3, 17, 'halogen'],
70
+ ['Ar', 'Argon', 3, 18, 'noble-gas'],
71
+ ['K', 'Potassium', 4, 1, 'alkali-metal'],
72
+ ['Ca', 'Calcium', 4, 2, 'alkaline-earth-metal'],
73
+ ['Sc', 'Scandium', 4, 3, 'transition-metal'],
74
+ ['Ti', 'Titanium', 4, 4, 'transition-metal'],
75
+ ['V', 'Vanadium', 4, 5, 'transition-metal'],
76
+ ['Cr', 'Chromium', 4, 6, 'transition-metal'],
77
+ ['Mn', 'Manganese', 4, 7, 'transition-metal'],
78
+ ['Fe', 'Iron', 4, 8, 'transition-metal'],
79
+ ['Co', 'Cobalt', 4, 9, 'transition-metal'],
80
+ ['Ni', 'Nickel', 4, 10, 'transition-metal'],
81
+ ['Cu', 'Copper', 4, 11, 'transition-metal'],
82
+ ['Zn', 'Zinc', 4, 12, 'transition-metal'],
83
+ ['Ga', 'Gallium', 4, 13, 'post-transition-metal'],
84
+ ['Ge', 'Germanium', 4, 14, 'metalloid'],
85
+ ['As', 'Arsenic', 4, 15, 'metalloid'],
86
+ ['Se', 'Selenium', 4, 16, 'nonmetal'],
87
+ ['Br', 'Bromine', 4, 17, 'halogen'],
88
+ ['Kr', 'Krypton', 4, 18, 'noble-gas'],
89
+ ['Rb', 'Rubidium', 5, 1, 'alkali-metal'],
90
+ ['Sr', 'Strontium', 5, 2, 'alkaline-earth-metal'],
91
+ ['Y', 'Yttrium', 5, 3, 'transition-metal'],
92
+ ['Zr', 'Zirconium', 5, 4, 'transition-metal'],
93
+ ['Nb', 'Niobium', 5, 5, 'transition-metal'],
94
+ ['Mo', 'Molybdenum', 5, 6, 'transition-metal'],
95
+ ['Tc', 'Technetium', 5, 7, 'transition-metal'],
96
+ ['Ru', 'Ruthenium', 5, 8, 'transition-metal'],
97
+ ['Rh', 'Rhodium', 5, 9, 'transition-metal'],
98
+ ['Pd', 'Palladium', 5, 10, 'transition-metal'],
99
+ ['Ag', 'Silver', 5, 11, 'transition-metal'],
100
+ ['Cd', 'Cadmium', 5, 12, 'transition-metal'],
101
+ ['In', 'Indium', 5, 13, 'post-transition-metal'],
102
+ ['Sn', 'Tin', 5, 14, 'post-transition-metal'],
103
+ ['Sb', 'Antimony', 5, 15, 'metalloid'],
104
+ ['Te', 'Tellurium', 5, 16, 'metalloid'],
105
+ ['I', 'Iodine', 5, 17, 'halogen'],
106
+ ['Xe', 'Xenon', 5, 18, 'noble-gas'],
107
+ ['Cs', 'Caesium', 6, 1, 'alkali-metal'],
108
+ ['Ba', 'Barium', 6, 2, 'alkaline-earth-metal'],
109
+ ['La', 'Lanthanum', 6, null, 'lanthanoid'],
110
+ ['Ce', 'Cerium', 6, null, 'lanthanoid'],
111
+ ['Pr', 'Praseodymium', 6, null, 'lanthanoid'],
112
+ ['Nd', 'Neodymium', 6, null, 'lanthanoid'],
113
+ ['Pm', 'Promethium', 6, null, 'lanthanoid'],
114
+ ['Sm', 'Samarium', 6, null, 'lanthanoid'],
115
+ ['Eu', 'Europium', 6, null, 'lanthanoid'],
116
+ ['Gd', 'Gadolinium', 6, null, 'lanthanoid'],
117
+ ['Tb', 'Terbium', 6, null, 'lanthanoid'],
118
+ ['Dy', 'Dysprosium', 6, null, 'lanthanoid'],
119
+ ['Ho', 'Holmium', 6, null, 'lanthanoid'],
120
+ ['Er', 'Erbium', 6, null, 'lanthanoid'],
121
+ ['Tm', 'Thulium', 6, null, 'lanthanoid'],
122
+ ['Yb', 'Ytterbium', 6, null, 'lanthanoid'],
123
+ ['Lu', 'Lutetium', 6, null, 'lanthanoid'],
124
+ ['Hf', 'Hafnium', 6, 4, 'transition-metal'],
125
+ ['Ta', 'Tantalum', 6, 5, 'transition-metal'],
126
+ ['W', 'Tungsten', 6, 6, 'transition-metal'],
127
+ ['Re', 'Rhenium', 6, 7, 'transition-metal'],
128
+ ['Os', 'Osmium', 6, 8, 'transition-metal'],
129
+ ['Ir', 'Iridium', 6, 9, 'transition-metal'],
130
+ ['Pt', 'Platinum', 6, 10, 'transition-metal'],
131
+ ['Au', 'Gold', 6, 11, 'transition-metal'],
132
+ ['Hg', 'Mercury', 6, 12, 'transition-metal'],
133
+ ['Tl', 'Thallium', 6, 13, 'post-transition-metal'],
134
+ ['Pb', 'Lead', 6, 14, 'post-transition-metal'],
135
+ ['Bi', 'Bismuth', 6, 15, 'post-transition-metal'],
136
+ ['Po', 'Polonium', 6, 16, 'post-transition-metal'],
137
+ ['At', 'Astatine', 6, 17, 'halogen'],
138
+ ['Rn', 'Radon', 6, 18, 'noble-gas'],
139
+ ['Fr', 'Francium', 7, 1, 'alkali-metal'],
140
+ ['Ra', 'Radium', 7, 2, 'alkaline-earth-metal'],
141
+ ['Ac', 'Actinium', 7, null, 'actinoid'],
142
+ ['Th', 'Thorium', 7, null, 'actinoid'],
143
+ ['Pa', 'Protactinium', 7, null, 'actinoid'],
144
+ ['U', 'Uranium', 7, null, 'actinoid'],
145
+ ['Np', 'Neptunium', 7, null, 'actinoid'],
146
+ ['Pu', 'Plutonium', 7, null, 'actinoid'],
147
+ ['Am', 'Americium', 7, null, 'actinoid'],
148
+ ['Cm', 'Curium', 7, null, 'actinoid'],
149
+ ['Bk', 'Berkelium', 7, null, 'actinoid'],
150
+ ['Cf', 'Californium', 7, null, 'actinoid'],
151
+ ['Es', 'Einsteinium', 7, null, 'actinoid'],
152
+ ['Fm', 'Fermium', 7, null, 'actinoid'],
153
+ ['Md', 'Mendelevium', 7, null, 'actinoid'],
154
+ ['No', 'Nobelium', 7, null, 'actinoid'],
155
+ ['Lr', 'Lawrencium', 7, null, 'actinoid'],
156
+ ['Rf', 'Rutherfordium', 7, 4, 'transition-metal'],
157
+ ['Db', 'Dubnium', 7, 5, 'transition-metal'],
158
+ ['Sg', 'Seaborgium', 7, 6, 'transition-metal'],
159
+ ['Bh', 'Bohrium', 7, 7, 'transition-metal'],
160
+ ['Hs', 'Hassium', 7, 8, 'transition-metal'],
161
+ ['Mt', 'Meitnerium', 7, 9, 'transition-metal'],
162
+ ['Ds', 'Darmstadtium', 7, 10, 'transition-metal'],
163
+ ['Rg', 'Roentgenium', 7, 11, 'transition-metal'],
164
+ ['Cn', 'Copernicium', 7, 12, 'transition-metal'],
165
+ ['Nh', 'Nihonium', 7, 13, 'post-transition-metal'],
166
+ ['Fl', 'Flerovium', 7, 14, 'post-transition-metal'],
167
+ ['Mc', 'Moscovium', 7, 15, 'post-transition-metal'],
168
+ ['Lv', 'Livermorium', 7, 16, 'post-transition-metal'],
169
+ ['Ts', 'Tennessine', 7, 17, 'halogen'],
170
+ ['Og', 'Oganesson', 7, 18, 'noble-gas'],
171
+ ];
172
+
173
+ /** Every element, ordered by atomic number. */
174
+ export const PERIODIC_ELEMENTS: readonly PeriodicElement[] = ROWS.map(
175
+ (row, index) => ({
176
+ atomicNumber: index + 1,
177
+ symbol: row[0],
178
+ name: row[1],
179
+ period: row[2],
180
+ group: row[3],
181
+ block: blockOf(index + 1, row[3]),
182
+ category: row[4],
183
+ }),
184
+ );
185
+
186
+ const BY_SYMBOL = new Map(
187
+ PERIODIC_ELEMENTS.map((element) => [element.symbol, element]),
188
+ );
189
+
190
+ /**
191
+ * Look up an element by its symbol.
192
+ * @param symbol - Chemical symbol, e.g. `Cl`. Case sensitive, as symbols are.
193
+ * @returns The element, or `undefined` when no element carries that symbol.
194
+ */
195
+ export function elementBySymbol(symbol: string): PeriodicElement | undefined {
196
+ return BY_SYMBOL.get(symbol);
197
+ }
198
+
199
+ /**
200
+ * Look up an element by its atomic number.
201
+ * @param atomicNumber - Proton count, 1 to 118.
202
+ * @returns The element, or `undefined` when it is outside the table.
203
+ */
204
+ export function elementByAtomicNumber(
205
+ atomicNumber: number,
206
+ ): PeriodicElement | undefined {
207
+ return PERIODIC_ELEMENTS[atomicNumber - 1];
208
+ }
209
+
210
+ function blockOf(atomicNumber: number, group: number | null): ElementBlock {
211
+ if (group === null) return 'f';
212
+ // Helium sits above the p block but its only electrons are 1s.
213
+ if (atomicNumber === 2) return 's';
214
+ if (group <= 2) return 's';
215
+ if (group <= 12) return 'd';
216
+ return 'p';
217
+ }
@@ -0,0 +1,27 @@
1
+ export type {
2
+ ElementBlock,
3
+ ElementCategory,
4
+ PeriodicElement,
5
+ } from './elements.ts';
6
+ export {
7
+ PERIODIC_ELEMENTS,
8
+ elementByAtomicNumber,
9
+ elementBySymbol,
10
+ } from './elements.ts';
11
+ export {
12
+ CATEGORY_LABELS,
13
+ CATEGORY_ORDER,
14
+ CATEGORY_SWATCHES,
15
+ UNKNOWN_SWATCH,
16
+ categorySwatch,
17
+ } from './categories.ts';
18
+ export type { Cell, ElementRange } from './layout.ts';
19
+ export {
20
+ COLUMN_COUNT,
21
+ INNER_TRANSITION_MARKERS,
22
+ INNER_TRANSITION_ROWS,
23
+ ROW_COUNT,
24
+ cellOf,
25
+ elementByArrowKey,
26
+ placedElements,
27
+ } from './layout.ts';