Skip to content

Survey Customization Recipe ​

Patterns for customizing Sibilance survey behavior and appearance.

Overview ​

This recipe covers ways to customize surveys, including styling, behavior, and integration patterns.

Styling ​

Custom Button Styles ​

tsx
import { FloatingMicButton } from '@sibilance.is/client/react';

function CustomButton() {
  const { voiceState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here'
  });

  return (
    <FloatingMicButton
      isConnected={voiceState.isConnected}
      onClick={toggleSession}
      style={{
        '--sibilance-primary-color': '#007bff',
        '--sibilance-background': '#ffffff',
        '--sibilance-border-radius': '50%',
        '--sibilance-shadow': '0 4px 12px rgba(0, 0, 0, 0.15)'
      } as React.CSSProperties}
    />
  );
}

Custom CSS ​

css
/* Override default styles */
.sibilance-microphone {
  --sibilance-primary-color: #007bff;
  --sibilance-background: #ffffff;
  --sibilance-border-radius: 50%;
}

.sibilance-microphone::part(button) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  box-shadow: 0 8px 16px rgba(102, 126, 234, 0.4);
}

.sibilance-microphone::part(button):hover {
  transform: scale(1.1);
  transition: transform 0.2s;
}

Behavior Customization ​

Auto-Start Survey ​

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here',
  autoStart: true  // Start automatically
}, {
  onComplete: (yaml) => {
    console.log('Survey completed!', yaml);
  }
});

Custom Instructions ​

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here',
  customInstructions: `
    Please be friendly and conversational.
    If the user seems confused, offer to clarify.
    Keep responses brief and to the point.
  `
});

Voice Configuration ​

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here',
  voiceConfig: {
    provider: 'gemini',  // or 'openai', 'vowel-prime'
    model: 'gemini-2.0-flash-exp',
    voiceId: 'alloy',  // OpenAI voice ID
    speakingRate: 1.0  // 0.5 to 2.0
  }
});

Conditional Logic ​

Show Survey Based on Conditions ​

tsx
function ConditionalSurvey() {
  const [shouldShow, setShouldShow] = useState(false);
  const { voiceState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here',
    autoStart: false
  });

  useEffect(() => {
    // Show survey after 5 seconds
    const timer = setTimeout(() => {
      setShouldShow(true);
    }, 5000);
    
    return () => clearTimeout(timer);
  }, []);

  if (!shouldShow) return null;

  return (
    <FloatingMicButton
      isConnected={voiceState.isConnected}
      onClick={toggleSession}
    />
  );
}

Survey Based on User Action ​

tsx
function ActionTriggeredSurvey() {
  const [showSurvey, setShowSurvey] = useState(false);
  const { voiceState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here',
    autoStart: false
  });

  return (
    <div>
      <button onClick={() => setShowSurvey(true)}>
        Start Survey
      </button>
      
      {showSurvey && (
        <FloatingMicButton
          isConnected={voiceState.isConnected}
          onClick={toggleSession}
        />
      )}
    </div>
  );
}

Integration Patterns ​

tsx
function ModalSurvey() {
  const [isOpen, setIsOpen] = useState(false);
  const { voiceState, surveyState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here'
  }, {
    onComplete: (yaml) => {
      console.log('Survey completed!', yaml);
      setIsOpen(false);
    }
  });

  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Open Survey
      </button>
      
      {isOpen && (
        <div className="modal">
          <div className="modal-content">
            <button onClick={() => setIsOpen(false)}>Close</button>
            
            {surveyState.isActive && (
              <div className="survey-status">
                Survey in progress...
              </div>
            )}
            
            <FloatingMicButton
              isConnected={voiceState.isConnected}
              onClick={toggleSession}
            />
          </div>
        </div>
      )}
    </>
  );
}

Inline Survey Widget ​

tsx
function InlineSurvey() {
  const { voiceState, surveyState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here'
  });

  return (
    <div className="inline-survey">
      <h3>Voice Survey</h3>
      
      <button onClick={toggleSession}>
        {voiceState.isConnected ? 'Stop Survey' : 'Start Survey'}
      </button>
      
      {surveyState.isActive && (
        <div className="progress">
          <p>Current step: {surveyState.currentStepId}</p>
          <p>Collected: {surveyState.collectedInfo.length} items</p>
        </div>
      )}
    </div>
  );
}