@captiveorigins/onepedigree-react 0.1.0-alpha.10 → 0.1.0-alpha.11

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.
@@ -234,7 +234,7 @@ export function PedigreeExplorer(props) {
234
234
  const individual = occurrence ? projection.individuals[occurrence.individualId] : undefined;
235
235
  const href = individual ? (props.getIndividualHref?.(individual) ?? null) : null;
236
236
  const close = () => choose(null);
237
- return (_jsxs("div", { ref: root, className: "op-explorer", style: { height: props.height ?? '32rem', ...(theme ? { ...themeStyle(theme, projection.view), background: 'var(--op-background)' } : {}) }, onKeyDown: onKeyDown, onWheel: onWheel, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, onPointerCancel: onPointerCancel, onClickCapture: (e) => {
237
+ return (_jsxs("div", { ref: root, className: "op-explorer", "data-legend": props.geneOverlay || props.genotypes ? '' : undefined, style: { height: props.height ?? '32rem', ...(theme ? { ...themeStyle(theme, projection.view), background: 'var(--op-background)' } : {}) }, onKeyDown: onKeyDown, onWheel: onWheel, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, onPointerCancel: onPointerCancel, onClickCapture: (e) => {
238
238
  // A drag ends with a click on the node: don't let it select.
239
239
  if (suppressClick.current) {
240
240
  suppressClick.current = false;
@@ -39,6 +39,8 @@ export type GenotypeDisplay = {
39
39
  records: ReadonlyMap<string, readonly GenotypeRecord[]>;
40
40
  /** Needed for sex-linked genes: the heterogametic sex has one copy (one dot). */
41
41
  sexOf?: (individualId: string) => SexClass;
42
+ /** Words for the key (translations). */
43
+ labels?: Partial<Record<'title' | 'two' | 'one' | 'none' | 'possible' | 'unknown' | 'suggested', string>>;
42
44
  };
43
45
  /** Allele dots for one gene (SVG, starting at 0,0, vertically centered on 0). */
44
46
  export declare function GenotypeDots({ gene, record, hemizygous, r, words }: {
package/dist/genetics.js CHANGED
@@ -51,8 +51,8 @@ function copies(record, mode, slots) {
51
51
  return { filled: 1, possible: 0, unknown: 0 };
52
52
  if (state === 'super')
53
53
  return { filled: slots, possible: 0, unknown: 0 };
54
- // visual: two copies for a recessive (or one when hemizygous); one assumed otherwise
55
- return { filled: slots === 1 || mode === 'recessive' ? slots : 1, possible: 0, unknown: 0 };
54
+ // visual: two copies for a recessive (or one when hemizygous); otherwise at least one, the other not known
55
+ return slots === 1 || mode === 'recessive' ? { filled: slots, possible: 0, unknown: 0 } : { filled: 1, possible: 0, unknown: 1 };
56
56
  }
57
57
  /** Allele dots for one gene (SVG, starting at 0,0, vertically centered on 0). */
58
58
  export function GenotypeDots({ gene, record, hemizygous = false, r = 4.5, words }) {
@@ -88,7 +88,7 @@ export function genotypeText(display, individualId, words = GENOTYPE_WORDS) {
88
88
  .join('; ');
89
89
  }
90
90
  /** Key for allele dots: each gene's color, and what the dots mean. */
91
- export function GenotypeKey({ display, labels = {} }) {
91
+ export function GenotypeKey({ display, labels = display.labels ?? {} }) {
92
92
  const l = { title: 'Genes', two: 'two copies', one: 'one copy', none: 'none', possible: 'possible (dashed)', unknown: 'not known', suggested: 'suggested from relatives', ...labels };
93
93
  const demo = { id: 'demo', label: '', color: '#7a625c', mode: 'recessive' };
94
94
  const sample = (record, text) => (_jsxs("li", { children: [_jsx("svg", { width: 22, height: 12, viewBox: "0 -6 22 12", "aria-hidden": "true", children: _jsx(GenotypeDots, { gene: demo, record: record, r: 4 }) }), text] }));
package/dist/styles.css CHANGED
@@ -142,11 +142,11 @@
142
142
  }
143
143
 
144
144
  /* Heritable trait overlay: genetic pedigree symbols (filled = visual, half = het, dot = possible het, open = not carrying). */
145
- .op-gene-outline { fill: var(--op-node-background); stroke: var(--op-label); stroke-width: 1.5px; }
145
+ .op-gene-outline { fill: var(--op-node-background, #fff); stroke: var(--op-label, #4c312c); stroke-width: 1.5px; }
146
146
  .op-gene-outline[data-dashed] { stroke-dasharray: 2 2; }
147
- .op-gene-fill { fill: var(--op-label); }
148
- .op-gene-ring { fill: none; stroke: var(--op-label); stroke-width: 1.25px; }
149
- .op-gene-text { font-size: 9px; fill: var(--op-label); }
147
+ .op-gene-fill { fill: var(--op-label, #4c312c); }
148
+ .op-gene-ring { fill: none; stroke: var(--op-label, #4c312c); stroke-width: 1.25px; }
149
+ .op-gene-text { font-size: 9px; fill: var(--op-label, #4c312c); }
150
150
  .op-gene[data-state='unknown'] .op-gene-outline { stroke: #9a8f8b; }
151
151
  .op-gene[data-state='unknown'] .op-gene-text { fill: #9a8f8b; }
152
152
  .op-gene-legends { position: absolute; left: 8px; bottom: 8px; z-index: 1; max-width: calc(100% - 16px); display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-end; }
@@ -162,10 +162,15 @@
162
162
 
163
163
  /* Allele dots: two per gene, one per copy. Filled = carries it (gene color), empty = normal copy,
164
164
  dashed = possible, grey dashed = not known. Shape carries the meaning, not color. */
165
- .op-dot { fill: var(--op-node-background); stroke: var(--op-label); stroke-width: 1.25px; }
165
+ .op-dot { fill: var(--op-node-background, #fff); stroke: var(--op-label, #4c312c); stroke-width: 1.25px; }
166
166
  .op-dot[data-dot='possible'] { stroke-dasharray: 1.6 1.6; }
167
167
  /* Suggested from relatives (not proven): the copy is drawn with a dashed edge. */
168
168
  .op-dot[data-inferred] { stroke-dasharray: 2 1.4; stroke-width: 1.5px; }
169
169
  .op-dot[data-dot='unknown'] { stroke: #9a8f8b; stroke-dasharray: 1.6 1.6; }
170
- .op-gene-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 50%; border: 1px solid var(--op-label); }
170
+ .op-gene-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 50%; border: 1px solid var(--op-label, #4c312c); }
171
171
  .op-genotype-key ul + ul { margin-top: 2px; }
172
+
173
+ /* With a gene legend, the legend sits under the drawing instead of covering it. */
174
+ .op-explorer[data-legend] { display: flex; flex-direction: column; }
175
+ .op-explorer[data-legend] > svg { flex: 1; min-height: 0; height: auto; }
176
+ .op-explorer[data-legend] .op-gene-legends { position: static; margin: 0 8px 8px; max-width: none; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@captiveorigins/onepedigree-react",
3
- "version": "0.1.0-alpha.10",
3
+ "version": "0.1.0-alpha.11",
4
4
  "description": "OnePedigree for React: server-renderable SVG pedigree views (all 13), an interactive explorer, headless hooks and CSS-variable styling.",
5
5
  "homepage": "https://github.com/mgilardi/onepedigree#readme",
6
6
  "bugs": {
@@ -46,7 +46,7 @@
46
46
  "node": ">=22"
47
47
  },
48
48
  "dependencies": {
49
- "@captiveorigins/onepedigree-core": "^0.1.0-alpha.10"
49
+ "@captiveorigins/onepedigree-core": "^0.1.0-alpha.11"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "react": ">=18.2"