> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twine.se/llms.txt
> Use this file to discover all available pages before exploring further.

# Raw Attribute

export const NodeMode = ({mode = 'data'}) => {
  const ENGINES = {
    data: [{
      label: 'Data Engine',
      href: '/data-engine'
    }],
    flow: [{
      label: 'Flow Engine',
      href: '/flow-engine'
    }],
    any: [{
      label: 'Data Engine',
      href: '/data-engine'
    }, {
      label: 'Flow Engine',
      href: '/flow-engine'
    }]
  };
  const engines = ENGINES[mode] || ENGINES.data;
  return <>
      <style>{`
        .node-mode {
          display: flex;
          flex-wrap: wrap;
          align-items: center;
          gap: 8px;
          margin: 0 0 20px;
        }
        .node-mode-label {
          font-size: 11px;
          font-weight: 600;
          text-transform: uppercase;
          letter-spacing: 0.05em;
          color: var(--colors-content-secondary, #6b7280);
        }
        .node-mode-pill {
          display: inline-flex;
          align-items: center;
          padding: 3px 10px;
          border-radius: 999px;
          font-size: 12px;
          font-weight: 600;
          text-decoration: none;
          color: inherit;
          background: rgb(var(--primary-light) / .15);
          border: 1px solid rgb(var(--primary-light) / .5);
        }
        .node-mode-pill:hover {
          background: rgb(var(--primary-light) / .25);
        }
      `}</style>
      <div className="node-mode">
        <span className="node-mode-label">Available in</span>
        {engines.map(engine => <a key={engine.label} className="node-mode-pill" href={engine.href}>
            {engine.label}
          </a>)}
      </div>
    </>;
};

export const NodePorts = ({nodeName, inputs = [], outputs = []}) => {
  if (inputs.length === 0 && outputs.length === 0) return null;
  const formatTypes = types => {
    if (!types || types.length === 0) return 'Any';
    if (Array.isArray(types)) return types.join(', ');
    return types;
  };
  const Card = ({port, side}) => <div className={`node-port-card node-port-card-${side}`}>
      <div className="node-port-head">
        <span className="node-port-name">{port.name}</span>
        <span className="node-port-id">{port.id}</span>
      </div>
      {port.doc && <div className="node-port-doc">{port.doc}</div>}
      <div className="node-port-tags">
        <span className="node-port-tag node-port-tag-types">{formatTypes(port.types)}</span>
        {port.required && <span className="node-port-tag node-port-tag-required">required</span>}
        {port.arity === 'many' && <span className="node-port-tag">many</span>}
        {port.defaultConnection && <span className="node-port-tag node-port-tag-default">default</span>}
      </div>
    </div>;
  return <>
      <style>{`
        .node-diagram {
          display: grid;
          grid-template-columns: 1fr auto 1fr;
          gap: 32px;
          align-items: stretch;
          margin: 24px 0 32px;
        }
        .node-diagram-col {
          display: flex;
          flex-direction: column;
          gap: 12px;
          min-width: 0;
        }
        .node-diagram-col-label {
          font-size: 11px;
          font-weight: 600;
          text-transform: uppercase;
          letter-spacing: 0.05em;
          color: var(--colors-content-secondary, #6b7280);
          margin-bottom: 4px;
        }
        .node-diagram-col-center {
          display: flex;
          align-items: stretch;
          justify-content: center;
          position: relative;
          /* Push the center node down so it aligns with the cards, not the column labels */
          padding-top: 27px;
        }
        .node-diagram-node {
          display: flex;
          align-items: center;
          justify-content: center;
          padding: 18px 14px;
          border-radius: 10px;
          background: rgb(var(--primary-light) / .15);
          border: 1.5px solid rgb(var(--primary-light) / .55);
          font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
          font-size: 15px;
          font-weight: 700;
          color: inherit;
          box-shadow: 0 1px 3px rgb(0 0 0 / .04);
          writing-mode: vertical-rl;
          transform: rotate(180deg);
          letter-spacing: 0.05em;
        }
        .node-port-card {
          position: relative;
          border: 1px solid rgb(var(--primary-light) / .25);
          border-radius: 8px;
          padding: 10px 12px;
          background: rgb(var(--primary-light) / .04);
          font-size: 12px;
          line-height: 1.4;
        }
        .node-port-card::after {
          content: '';
          position: absolute;
          top: 50%;
          width: 32px;
          border-top: 1px dashed rgb(var(--primary-light) / .7);
        }
        .node-port-card-left::after {
          right: -32px;
        }
        .node-port-card-right::after {
          left: -32px;
        }
        .node-port-head {
          display: flex;
          align-items: baseline;
          justify-content: space-between;
          gap: 8px;
          margin-bottom: 4px;
        }
        .node-port-name {
          font-weight: 600;
          font-size: 13px;
          color: inherit;
        }
        .node-port-id {
          font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
          font-size: 10.5px;
          color: var(--colors-content-secondary, #6b7280);
        }
        .node-port-doc {
          color: #4b5563;
          margin-bottom: 6px;
        }
        .dark .node-port-doc,
        html.dark .node-port-doc,
        :is(.dark, [data-theme="dark"]) .node-port-doc {
          color: #d1d5db;
        }
        .node-port-tags {
          display: flex;
          flex-wrap: wrap;
          gap: 4px;
        }
        .node-port-tag {
          display: inline-flex;
          align-items: center;
          padding: 2px 6px;
          border-radius: 4px;
          font-size: 10px;
          font-weight: 600;
          background: rgb(var(--primary-light) / .15);
          color: var(--colors-content-secondary, #6b7280);
          text-transform: lowercase;
          letter-spacing: 0.02em;
        }
        .node-port-tag-types {
          font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
          text-transform: none;
          background: rgb(var(--primary-light) / .25);
          color: inherit;
        }
        .node-port-tag-required {
          background: var(--colors-warning-light, #fef3c7);
          color: var(--colors-warning, #b45309);
        }
        .node-port-tag-default {
          background: var(--colors-accent-light, #ede9fe);
          color: var(--colors-accent, #7c3aed);
        }
        @media (max-width: 720px) {
          .node-diagram {
            grid-template-columns: 1fr;
            gap: 16px;
          }
          .node-diagram-col-center {
            order: -1;
          }
          .node-port-card::before,
          .node-port-card::after {
            display: none !important;
          }
        }
      `}</style>
      <div className="node-diagram">
        <div className="node-diagram-col node-diagram-col-left">
          {inputs.length > 0 && <div className="node-diagram-col-label">Inputs</div>}
          {inputs.map(p => <Card key={p.id} port={p} side="left" />)}
        </div>
        <div className="node-diagram-col-center">
          <div className="node-diagram-node">{nodeName}</div>
        </div>
        <div className="node-diagram-col node-diagram-col-right">
          {outputs.length > 0 && <div className="node-diagram-col-label">Outputs</div>}
          {outputs.map(p => <Card key={p.id} port={p} side="right" />)}
        </div>
      </div>
    </>;
};

<NodeMode mode="data" />

Reads a value from the model as a raw term. Unlike Attribute, the value is
emitted exactly as it sits on the model — no dated-property wrapping, no
list fan-out. Use this to grab a whole map or list (e.g. a Hibob custom
table) that downstream nodes will iterate or pick apart.

### Configuration

* **Path** — dot-separated sequence of keys to walk into the model. `[]`
  is not supported in raw paths — give the path up to the list and let
  Raw Each iterate.

### Tips

* Pair with Raw Each to iterate over a list value.
* Pair with Raw Read or Wrap Raw to consume a scalar / nested map.

## Ports

<NodePorts
  nodeName="Raw Attribute"
  inputs={[
{ id: 'default_in', name: 'In', doc: 'Default input port', types: 'Any', required: true, defaultConnection: true },
]}
  outputs={[
{ id: 'default_out', name: 'Out', doc: 'Default output port', types: 'Any', required: true, defaultConnection: true },
]}
/>
